Emperor_Shun_Reading/electron/controller/os.js

634 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

'use strict';
const _ = require('lodash');
const path = require('path');
const { Controller } = require('ee-core');
const {
app: electronApp, dialog, shell, Notification,
powerMonitor, screen, nativeTheme
} = require('electron');
const Conf = require('ee-core/config');
const Ps = require('ee-core/ps');
const Services = require('ee-core/services');
const Addon = require('ee-core/addon');
const { getNetworkIFaceOne, getMac, getAllMac, getAllPhysicsMac } = require('@lzwme/get-physical-address');
const os = require('os');
const shutdown = require('electron-shutdown-command');
// 终端命令
const { exec, execSync, execFile } = require("child_process");
// 声音控制库 https://github.com/LinusU/node-loudness
const loudness = require("loudness");
// 文件处理
const fs = require('fs');
/**
* 操作系统 - 功能demo
* @class
*/
class OsController extends Controller {
constructor(ctx) {
super(ctx);
}
/**
* 所有方法接收两个参数
* @param args 前端传的参数
* @param event - ipc通信时才有值。详情见控制器文档
*/
// 获取所有的网卡-无参数
async getAllMac(args) {
// 文档说明 https://github.com/lzwme/get-physical-address/blob/main/.github/README_zh-CN.md
const list = getAllPhysicsMac();
return list;
}
// 查找到指定进程并关闭? 注意 进程要全, 不然容易误杀
deviceKillName(name) {
// 最新 taskkill /F /IM program.exe 这个命令一句话能直接杀掉进程
const self = this;
let rebootShell = "tasklist|findstr " + name;
let command = exec(rebootShell, function (err, stdout, stderr) {
if (err || stderr) {
console.log("tasklist failed" + err + stderr);
} else {
const lines = stdout.split('\n')
console.log(lines);
for (let index = 0; index < lines.length; index++) {
const element = lines[index];
const strs = element.split(' ')
const firstNumber = strs.find(item => !isNaN(Number(item)) && item != '')
console.log('jincheng id :' + firstNumber);
self.deviceKillPid(firstNumber)
}
}
});
command.stdin.end();
command.on("close", function (code) {
console.log("tasklist", code);
});
}
// 杀掉pid 进程
deviceKillPid(pid) {
let rebootShell = "tskill " + pid;
let command = exec(rebootShell, function (err, stdout, stderr) {
if (err || stderr) {
console.log("tskill failed" + err + stderr);
}
})
command.stdin.end();
command.on("close", function (code) {
console.log("tskill", code);
});
}
// 启动指定目录的程序 可能有权限问题, 方案1 打包后管理员权限执行, 2 按照egg 的方案把需要执行的程序拷贝到安装包
deviceStarExe(path) {
let rebootShell = 'start ' + path;
exec(rebootShell);
}
/**
* 设备关机
*/
deviceShutdown() {
// 关机
// let shutdownShell = "shutdown -s -t 00";
console.log('deviceShutdown=============')
shutdown.shutdown();
return true;
}
deviceRestart(args) {
// 重启
let rebootShell = "shutdown -r -t 0";
let command = exec(rebootShell, function (err, stdout, stderr) {
if (err || stderr) {
console.log("shutdown failed" + err + stderr);
}
});
command.stdin.end();
command.on("close", function (code) {
console.log("shutdown", code);
});
}
// 同步执行 声音设置 支持0-100
async deviceLoudness(args) {
const value = args.value;
//操作系统平台
const pf = os.platform();
console.log("OS: " + pf)
// 特殊处理以下
if (pf == "linux") {
let shellStr = "amixer -D pulse set Master " + value + "% unmute"
if (value == 0) {
shellStr = "amixer -D pulse set Master mute"
}
// else{
// shellStr = "amixer -c 0 set Master,0 100%,80% unmute"
// }
let command = exec(shellStr, function (err, stdout, stderr) {
if (err || stderr) {
console.log("amixer failed" + err + stderr);
}
});
command.stdin.end();
command.on("close", function (code) {
console.log("amixer", code);
});
return;
} else {
/// 兼容模式, try catch 如果第一种方式报错, 在采用第二种
try {
//0 为静音
if (value == 0) {
await loudness.setMuted(true)
return await loudness.getMuted()
}
// 设置声音改为不静音 且设置声音
await loudness.setMuted(false)
await loudness.setVolume(value)
const newValue = await loudness.getVolume();
return newValue;
} catch {
const maxVolume = 65535;
let volumeValue = Math.round((value / 100) * maxVolume);
// 确保音量值在有效范围内
volumeValue = Math.max(0, Math.min(maxVolume, volumeValue));
// 将音量值转换为字符串
const valueStr = volumeValue.toString();
let excPath = path.join(Ps.getExtraResourcesDir(), 'nircmd.exe');
execFile(excPath, ['setsysvolume', valueStr], (error, stdout, stderr) => {
if (error) {
console.error(' Nircmd error: ', error);
return;
}
console.log('Nircmd ok ');
});
return value;
}
}
}
// 获取电脑信息
async getOSMessage(args) {
var OSDic = {};
var dealTime = (seconds) => {
var seconds = seconds | 0;
var day = (seconds / (3600 * 24)) | 0;
var hours = ((seconds - day * 3600) / 3600) | 0;
var minutes = ((seconds - day * 3600 * 24 - hours * 3600) / 60) | 0;
var second = seconds % 60;
(day < 10) && (day = '0' + day);
(hours < 10) && (hours = '0' + hours);
(minutes < 10) && (minutes = '0' + minutes);
(second < 10) && (second = '0' + second);
return [day, hours, minutes, second].join(':');
};
var dealMem = (mem) => {
var G = 0,
M = 0,
KB = 0;
(mem > (1 << 30)) && (G = (mem / (1 << 30)).toFixed(2));
(mem > (1 << 20)) && (mem < (1 << 30)) && (M = (mem / (1 << 20)).toFixed(2));
(mem > (1 << 10)) && (mem > (1 << 20)) && (KB = (mem / (1 << 10)).toFixed(2));
return G > 0 ? G + 'G' : M > 0 ? M + 'M' : KB > 0 ? KB + 'KB' : mem + 'B';
};
//cpu架构
const arch = os.arch();
// console.log("cpu架构" + arch);
OSDic["arch"] = arch;
//操作系统内核
const kernel = os.type();
// console.log("操作系统内核:" + kernel);
OSDic["kernel"] = kernel;
//操作系统平台
const pf = os.platform();
// console.log("平台:" + pf);
OSDic["pf"] = pf;
//系统开机时间
const uptime = os.uptime();
// console.log("开机时间:" + dealTime(uptime));
OSDic["uptime"] = uptime;
//主机名
const hn = os.hostname();
// console.log("主机名:" + hn);
OSDic["hostname"] = hn;
// //主目录
// const hdir = os.homedir();
// console.log("主目录:" + hdir);
// OSDic["homedir"] = hdir;
//内存
const totalMem = os.totalmem();
const freeMem = os.freemem();
// console.log("内存大小:" + dealMem(totalMem) + ' 空闲内存:' + dealMem(freeMem));
OSDic["totalmem"] = totalMem;
OSDic["freeMem"] = freeMem;
//cpu
const cpus = os.cpus();
OSDic["cpuModel"] = cpus[0]["model"];
// OSDic["cpus"] = cpus;
// console.log('*****cpu信息*******');
// cpus.forEach((cpu, idx, arr) => {
// var times = cpu.times;
// console.log(`cpu${idx}`);
// console.log(`型号:${cpu.model}`);
// console.log(`频率:${cpu.speed}MHz`);
// console.log(`使用率:${((1 - times.idle / (times.idle + times.user + times.nice + times.sys + times.irq)) * 100).toFixed(2)}%`);
// });
try {
const volumeValue = await loudness.getVolume()
OSDic["volume"] = volumeValue;
console.log('volumeValue' + volumeValue);
} catch (error) {
console.log(error)
}
return OSDic;
}
// const volume = await loudness.getVolume()
// OSDic["volume"] = volume;
// return OSDic;
// }
/**
* 获取当前目录的配置
* @param {*} name 配置文件名
* @returns
*/
getCurrentDirectoryConfig(name) {
let configPath = '';
configPath = path.join(Ps.getExtraResourcesDir(), name);
console.log(configPath)
// let configJSON = null;
let dataString = null;
try {
// 同步读取配置文件
dataString = fs.readFileSync(configPath, 'utf8');
// 解析 JSON 格式的配置数据
// configJSON = JSON.parse(data);
// console.log('读取到的配置:', configJSON);
// 在这里可以根据需要使用配置数据进行操作
} catch (err) {
console.error('无法读取配置文件:', err);
}
return dataString;
}
/**
* 消息提示对话框
*/
messageShow() {
dialog.showMessageBoxSync({
type: 'info', // "none", "info", "error", "question" 或者 "warning"
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息'
})
return '打开了消息框';
}
/**
* 消息提示与确认对话框
*/
messageShowConfirm() {
const res = dialog.showMessageBoxSync({
type: 'info',
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息',
cancelId: 1, // 用于取消对话框的按钮的索引
defaultId: 0, // 设置默认选中的按钮
buttons: ['确认', '取消'], // 按钮及索引
})
let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';
return data;
}
/**
* 选择目录
*/
selectFolder() {
const filePaths = dialog.showOpenDialogSync({
properties: ['openDirectory', 'createDirectory']
});
if (_.isEmpty(filePaths)) {
return null
}
return filePaths[0];
}
/**
* 打开目录
*/
openDirectory(args) {
if (!args.id) {
return false;
}
let dir = '';
if (path.isAbsolute(args.id)) {
dir = args.id;
} else {
dir = electronApp.getPath(args.id);
}
shell.openPath(dir);
return true;
}
/**
* 选择图片
*/
selectPic() {
const filePaths = dialog.showOpenDialogSync({
title: 'select pic',
properties: ['openFile'],
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
]
});
if (_.isEmpty(filePaths)) {
return null
}
return filePaths[0];
}
/**
* 加载视图内容
*/
loadViewContent(args) {
const { type, content } = args;
let contentUrl = content;
if (type == 'html') {
contentUrl = path.join('file://', electronApp.getAppPath(), content);
}
Services.get('os').createBrowserView(contentUrl);
return true
}
/**
* 移除视图内容
*/
removeViewContent() {
Services.get('os').removeBrowserView();
return true
}
/**
* 打开新窗口
*/
createWindow(args) {
const { type, content, windowName, windowTitle } = args;
let contentUrl = null;
if (type == 'html') {
contentUrl = path.join('file://', electronApp.getAppPath(), content)
} else if (type == 'web') {
contentUrl = content;
} else if (type == 'vue') {
let addr = 'http://localhost:17680'
if (Ps.isProd()) {
const mainServer = Conf.getValue('mainServer');
if (Conf.isFileProtocol(mainServer)) {
addr = mainServer.protocol + path.join(Ps.getHomeDir(), mainServer.indexPath);
} else {
addr = mainServer.protocol + mainServer.host + ':' + mainServer.port;
}
}
contentUrl = addr + content;
} else {
// some
}
console.log('contentUrl: ', contentUrl);
let opt = {
title: windowTitle
}
const win = Addon.get('window').create(windowName, opt);
const winContentsId = win.webContents.id;
// load page
win.loadURL(contentUrl);
return winContentsId;
}
/**
* 获取窗口contents id
*/
getWCid(args) {
// 主窗口的name默认是main其它窗口name开发者自己定义
const name = args;
const id = Addon.get('window').getWCid(name);
return id;
}
/**
* 加载扩展程序
*/
// async loadExtension (args) {
// const crxFile = args[0];
// if (_.isEmpty(crxFile)) {
// return false;
// }
// const extensionId = path.basename(crxFile, '.crx');
// const chromeExtensionDir = chromeExtension.getDirectory();
// const extensionDir = path.join(chromeExtensionDir, extensionId);
// Log.info("[api] [example] [loadExtension] extension id:", extensionId);
// unzip(crxFile, extensionDir).then(() => {
// Log.info("[api] [example] [loadExtension] unzip success!");
// chromeExtension.load(extensionId);
// });
// return true;
// }
/**
* 创建系统通知
*/
sendNotification(args, event) {
const { title, subtitle, body, silent } = args;
if (!Notification.isSupported()) {
return '当前系统不支持通知';
}
let options = {};
if (!_.isEmpty(title)) {
options.title = title;
}
if (!_.isEmpty(subtitle)) {
options.subtitle = subtitle;
}
if (!_.isEmpty(body)) {
options.body = body;
}
if (!_.isEmpty(silent)) {
options.silent = silent;
}
Services.get('os').createNotification(options, event);
return true
}
/**
* 电源监控
*/
initPowerMonitor(args, event) {
const channel = 'controller.os.initPowerMonitor';
powerMonitor.on('on-ac', (e) => {
let data = {
type: 'on-ac',
msg: '接入了电源'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('on-battery', (e) => {
let data = {
type: 'on-battery',
msg: '使用电池中'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('lock-screen', (e) => {
let data = {
type: 'lock-screen',
msg: '锁屏了'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('unlock-screen', (e) => {
let data = {
type: 'unlock-screen',
msg: '解锁了'
}
event.reply(`${channel}`, data)
});
return true
}
/**
* 获取屏幕信息
*/
getScreen(args) {
let data = [];
let res = {};
if (args == 0) {
let res = screen.getCursorScreenPoint();
data = [
{
title: '横坐标',
desc: res.x
},
{
title: '纵坐标',
desc: res.y
},
]
return data;
}
if (args == 1) {
res = screen.getPrimaryDisplay();
}
if (args == 2) {
let resArr = screen.getAllDisplays();
// 数组,只取一个吧
res = resArr[0];
}
// Log.info('[electron] [ipc] [example] [getScreen] res:', res);
data = [
{
title: '分辨率',
desc: res.bounds.width + ' x ' + res.bounds.height
},
{
title: '单色显示器',
desc: res.monochrome ? '是' : '否'
},
{
title: '色深',
desc: res.colorDepth
},
{
title: '色域',
desc: res.colorSpace
},
{
title: 'scaleFactor',
desc: res.scaleFactor
},
{
title: '加速器',
desc: res.accelerometerSupport
},
{
title: '触控',
desc: res.touchSupport == 'unknown' ? '不支持' : '支持'
},
]
return data;
}
/**
* 获取系统主题
*/
getTheme() {
let theme = 'system';
if (nativeTheme.shouldUseHighContrastColors) {
theme = 'light';
} else if (nativeTheme.shouldUseInvertedColorScheme) {
theme = 'dark';
}
return theme;
}
/**
* 设置系统主题
*/
setTheme(args) {
// TODO 好像没有什么明显效果
nativeTheme.themeSource = args;
return args;
}
}
OsController.toString = () => '[class OsController]';
module.exports = OsController;