11import Command from '@/main/utils/Command'
22import { isMacOS , isWindows } from '@/shared/utils/utils2'
3- import { PowerShell } from '@/main/helpers/constant'
4- import OS from '@/main/utils/OS'
3+ import { PowerShell , WINDOWS_API_FILE_NAME } from '@/main/helpers/constant'
4+ import nodePath from 'path'
5+ import GetCorePath from '@/shared/helpers/GetCorePath'
56
67export default class ProcessExtend {
8+ static _ffiModule = null ;
9+ static _initFfi ( ) {
10+ if ( ! ProcessExtend . _ffiModule ) {
11+ ProcessExtend . _ffiModule = require ( 'koffi' )
12+ ProcessExtend . _ffiModule . config ( { max_async_calls :256 } )
13+ }
14+ return ProcessExtend . _ffiModule
15+ }
716 /**
817 * 杀死进程和子进程
918 * @param pid {number}
@@ -22,14 +31,12 @@ export default class ProcessExtend {
2231 }
2332 if ( isWindows ) {
2433 //taskkill杀不存在的进程会有标准错误,从而引发异常
25- await Command . exec ( `taskkill /f /t /pid ${ pid } ` ) ;
34+ await Command . exec ( `taskkill /f /t /pid ${ pid } ` )
2635 } else {
27- await Command . sudoExec ( `kill ${ pid } ` ) ;
36+ await Command . sudoExec ( `kill ${ pid } ` )
2837 }
2938 // eslint-disable-next-line no-empty
30- } catch {
31-
32- }
39+ } catch { }
3340 }
3441
3542 static async getParentPid ( pid ) {
@@ -57,57 +64,36 @@ export default class ProcessExtend {
5764 try {
5865 if ( isWindows ) {
5966 //taskkill杀不存在的进程会有标准错误,从而引发异常
60- await Command . exec ( `taskkill /f /t /im ${ name } .exe` ) ;
67+ await Command . exec ( `taskkill /f /t /im ${ name } .exe` )
6168 } else {
6269 //pkill杀不存在的进程会有标准错误,从而引发异常
63- await Command . sudoExec ( `pkill ${ name } ` ) ;
70+ await Command . sudoExec ( `pkill ${ name } ` )
6471 }
6572 // eslint-disable-next-line no-empty
66- } catch {
67-
68- }
73+ } catch { }
6974 }
7075
7176 static pidIsRunning ( pid ) {
7277 try {
73- process . kill ( pid , 0 ) ;
74- return true ;
78+ process . kill ( pid , 0 )
79+ return true
7580 } catch ( e ) {
76- return false ;
81+ return false
7782 }
7883 }
7984
8085 /**
81- * 根据pid,获取进程路径。Windows下,winShell=false,不支持并发,但是速度快。winShell=true,支持并发,但是速度慢。
86+ * 根据pid,获取进程路径
8287 * @param pid {number}
83- * @param winShell {boolean}
8488 * @returns {Promise<*|null> }
8589 */
86- static async getPathByPid ( pid , winShell = false ) {
90+ static async getPathByPid ( pid ) {
8791 try {
8892 pid = parseInt ( pid )
8993 let path
9094
9195 if ( isWindows ) {
92- if ( winShell ) {
93- const versionStr = OS . getVersion ( )
94- const [ major , minor , build ] = versionStr . split ( '.' ) . map ( Number )
95- if ( major === 10 && build >= 22000 ) {
96- //Windows 11: 版本号从 10.0.22000 开始。Windows11 废弃了 wmic
97- const commandStr = `(Get-Process -Id ${ pid } ).MainModule.FileName`
98- const resStr = await Command . exec ( commandStr , { shell : PowerShell } )
99- path = resStr . trim ( ) . split ( '\n' ) [ 0 ]
100- } else {
101- const commandStr = `wmic process where processid=${ pid } get executablepath`
102- const resStr = await Command . exec ( commandStr )
103- path = resStr . trim ( ) . split ( '\n' ) [ 1 ]
104- }
105- } else {
106- const hmc = require ( 'hmc-win32' )
107- path = await hmc . getProcessFilePath2 ( pid ) //getProcessFilePath2暂不支持并发
108- path = path ?? ''
109- path = path . startsWith ( '\\Device\\HarddiskVolume' ) ? '' : path //过滤掉 getProcessFilePath2 错误的path
110- }
96+ path = await ProcessExtend . getPathByPidForWindows ( pid )
11197 } else {
11298 const commandStr = `lsof -p ${ pid } -a -w -d txt -Fn|awk 'NR==3{print}'|sed "s/n//"`
11399 const resStr = await Command . exec ( commandStr )
@@ -120,18 +106,47 @@ export default class ProcessExtend {
120106 }
121107 }
122108
109+ static async getNameByPidForWindows ( pid ) {
110+ try {
111+ const koffi = ProcessExtend . _initFfi ( )
112+ const libPath = nodePath . join ( GetCorePath . getParentDir ( ) , WINDOWS_API_FILE_NAME )
113+ const lib = koffi . load ( libPath )
114+ const getProcessName = lib . func ( 'getProcessName' , 'str' , [ 'int' ] )
115+ // 个别进程的 getProcessName 比 getProcessPath 更耗时
116+ return await new Promise ( ( resolve , reject ) => {
117+ getProcessName . async ( pid , ( err , res ) => {
118+ resolve ( res ?? '' )
119+ } )
120+ } )
121+ } catch ( e ) {
122+ return null
123+ }
124+ }
125+
126+ static async getPathByPidForWindows ( pid ) {
127+ try {
128+ const koffi = ProcessExtend . _initFfi ( )
129+ const libPath = nodePath . join ( GetCorePath . getParentDir ( ) , WINDOWS_API_FILE_NAME )
130+ const lib = koffi . load ( libPath )
131+ const getProcessPath = lib . func ( 'getProcessPath' , 'str' , [ 'int' ] )
132+ return getProcessPath ( pid )
133+ } catch {
134+ return null
135+ }
136+ }
137+
123138 /**
124139 *
125140 * @param options {object}
126141 * @returns {Promise<[]|{path: *, name: *, pid: *, ppid: *}[]> }
127142 */
128- static async getList ( options = { } ) {
143+ static async getList ( options = { } ) {
129144 if ( isMacOS ) {
130- return await this . getListForMacOS ( options ) ;
145+ return await this . getListForMacOS ( options )
131146 } else if ( isWindows ) {
132- return await this . getListForWindows ( options ) ;
147+ return await this . getListForWindows ( options )
133148 }
134- return [ ] ;
149+ return [ ]
135150 }
136151
137152 static async getListForMacOS ( options = { } ) {
@@ -150,24 +165,22 @@ export default class ProcessExtend {
150165 command += `|grep -F -v '.dylib'|awk '{print $1,$2,$3,$10}'`
151166 try {
152167 let str = await Command . sudoExec ( command )
153- str = str . trim ( ) ;
154- if ( ! str ) {
155- return [ ] ;
168+ str = str . trim ( )
169+ if ( ! str ) {
170+ return [ ]
156171 }
157- let list = str . split ( '\n' ) ;
172+ let list = str . split ( '\n' )
158173
159- list = list . map ( item => {
160- let arr = item . split ( ' ' ) ;
161- let name , pid , ppid , path ;
162- [ name , pid , ppid , path ] = arr ;
163- return { name, pid, ppid, path} ;
164- } ) ;
174+ list = list . map ( ( item ) => {
175+ let arr = item . split ( ' ' )
176+ const [ name , pid , ppid , path ] = arr
177+ return { name, pid, ppid, path }
178+ } )
165179
166- return list ;
180+ return list
167181 } catch ( e ) {
168182 return [ ]
169183 }
170-
171184 }
172185
173186 static async getListForWindows ( options = { } ) {
@@ -188,15 +201,14 @@ export default class ProcessExtend {
188201 return [ ]
189202 }
190203 let list = str . split ( / \r ? \n \r ? \n / )
191- list = list . map ( item => {
204+ list = list . map ( ( item ) => {
192205 let lineArr = item . split ( / \r ? \n / )
193206
194- let arr = lineArr . map ( line => {
207+ let arr = lineArr . map ( ( line ) => {
195208 return line . split ( ' : ' ) [ 1 ] ?. trim ( )
196209 } )
197210
198- let name , pid , ppid , path ;
199- [ name , pid , ppid , path ] = arr
211+ const [ name , pid , ppid , path ] = arr
200212 return { name, pid, ppid, path }
201213 } )
202214 return list
0 commit comments