前言
我们如何通过Electron来检测一些应用程序的状态呢,如:未响应;
- 文档地址 EnumWindows IsHungAppWindow GetWindowThreadProcessId NodeJs——如何获取Windows电脑指定应用进程信息
内容
获取指定应用程序PID
通过exec
执行cmd命令查询指定应用的PID,并通过electron-store
存储获取到的PID,可参考NodeJs——如何获取Windows电脑指定应用进程信息;
/**
* 获取指定应用程序的PID | 只考虑win和linux
* @param exeName
*/
export function cmdFindPidList (exeName, callbackFun) {
const cmd = process.platform === 'win32' ? `tasklist -V|findstr "${exeName}" ` : `ps aux | grep ${exeName}`;
let pids = [];
exec(cmd, (err, stdout, stderr) => {
if (err) {
callbackFun(pids);
return
}
stdout.split('n').filter(item => {
const p = item.trim().split(/s /)
// p[0] 应用程序名称 p[1] 应用程序PID
if (p[0] && p[1]) {
pids.push(p[1]);
}
})
callbackFun(pids);
})
}
// 调用
cmdFindPidList('App.exe', (pids) => {
// 封装的`electron-store`存储
setStore('AppPids', pids)
})
调用user32.dll方法
代码语言:javascript复制const User32 = ffi.Library('user32.dll', {
EnumWindows: ['bool', ['pointer', 'long']],
GetWindowThreadProcessId: ['int', ['long', 'pointer']],
IsHungAppWindow: ['bool', ['long']]
})
const EnumWindowsProc = ffi.Callback('bool', ['long', 'int32'], function (hwnd, lParam) {
let pids = getStore('AppPids')
let pidBuff = Buffer.alloc(255)
let threadId = User32.GetWindowThreadProcessId(hwnd, pidBuff)
let pid = String(pidBuff.readInt32LE(0))
if (pids.includes(pid) && User32.IsHungAppWindow(hwnd)) {
// TODO 检测到程序窗口未响应处理方法
}
return true
})
// 调用
User32.EnumWindows(EnumWindowsProc, 0)
tasklist(推荐)
代码语言:javascript复制通过webworker新起一个线程进行检测
import { exec } from 'child_process'
onmessage = function (e) {
console.info(`worker: ${e.data}`)
setInterval(() => {
try {
exec("tasklist /V /FI "STATUS ne RUNNING" | findstr "xxxx.exe"", (err, stdout, stderr) => {
if (!err) {
stdout.split('n').filter(item => {
const p = item.trim().split(/s /)
// p[0] 应用程序名称 p[1] 应用程序PID 断开连接的时候p[2]会话名会没有一定要注意
if (p[0] ==='xxxx.exe' && p[1]) {
try {
exec(`taskkill /F /PID ${p[1]} /T`, (error, stdout, stderr) => {
if (!error) console.info(`worker: 清除无响应xxxx.exe成功 ===> p[0](应用名称) => ${p[0]}, p[1](应用程序PID) => ${p[1]}`)
})
} catch (e) {
console.error(`worker: 清除无响应xxxx.exe失败 ===> ${e}`)
}
}
})
}
})
} catch (e) {
console.error(`worker:关闭无响应xxxx.exe,${e}`)
}
}, 10000)
}
BAT脚本
代码语言:javascript复制@echo off
:start
:: 检测状态为未相应的应用进程 | 所有不理解的命令均可通过帮助进行查看,示例如下
:: for /?
for /f "skip=3 tokens=2 " %%i in ('tasklist /V /FI "STATUS ne RUNNING" /FI "imageNAME eq xxx.exe"') do (
::日志输出文件主要看bat启动位置
echo "�te% %time% 记录无响应的应用进程PID: %%i" >> "exeStatus.txt"
for /f "tokens=3* delims=: " %%j in ('find /C "%%i" exeStatus.txt') do (
::大于3次
if %%j GTR 3 (
echo "�te% %time% 开始清除出现%%j次无响应的应用进程PID: %%i">> "DelExePid.txt"
taskkill /F /PID %%i /T >> "DelExePid.txt"
findstr /V %%i "exeStatus.txt" > "exeStatus.tmp"
move /Y exeStatus.tmp exeStatus.txt
)
)
)
::10s检测一次
choice /t 10 /d y /n > null
goto start