依旧漂泊 发表于 2020-7-16 14:16:16

通过进程名获取进程路径[已解决]

本帖最后由 依旧漂泊 于 2020-7-19 01:13 编辑

https://www.autoitx.com/forum.ph ... 8%B3%CC%C2%B7%BE%B6
这里引用afan版主给出的代码,但是这里有一个问题,在64位系统编译成64位版本可以正常获取32位与64位进程的路径,
但是编译成32位版本,只能获取32位进程的路径,64位进程的路径获取不到。
因为我必须编译成32位版本。所以能不能编译成32位版本获取32位与64位进程的路径
解决方法:请参照afan版主,以我的功力写不出来,我还是直接编译成64位版本.

$PID = ProcessExists("explorer.exe")
MsgBox(0, "", _WinAPI_GetModuleFileNameEx($PID))


Func _WinAPI_CloseHandle($hObject)
      Local $aResult = DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hObject)
      If @error Then Return SetError(@error, @extended, False)
      Return $aResult
EndFunc   ;==>_WinAPI_CloseHandle
Func _WinAPI_GetCurrentProcessID()
      Local $aResult = DllCall("kernel32.dll", "dword", "GetCurrentProcessId")
      If @error Then Return SetError(@error, @extended, 0)
      Return $aResult
EndFunc   ;==>_WinAPI_GetCurrentProcessID
Func _WinAPI_GetModuleFileNameEx($PID = 0)
      If Not $PID Then
                $PID = _WinAPI_GetCurrentProcessID()
                If Not $PID Then
                        Return SetError(1, 0, 0)
                EndIf
      EndIf
      Local $hProcess = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'dword', 0x00000410, 'int', 0, 'dword', $PID)
      If (@error) Or (Not $hProcess) Then
                Return SetError(1, 0, '')
      EndIf
      Local $tPath = DllStructCreate('wchar')
      Local $Ret = DllCall('psapi.dll', 'int', 'GetModuleFileNameExW', 'ptr', $hProcess, 'ptr', 0, 'ptr', DllStructGetPtr($tPath), 'int', 1024)
      If (@error) Or (Not $Ret) Then
                $Ret = 0
      EndIf
      _WinAPI_CloseHandle($hProcess)
      If Not IsArray($Ret) Then
                Return SetError(1, 0, '')
      EndIf
      Return DllStructGetData($tPath, 1)
EndFunc   ;==>_WinAPI_GetModuleFileNameEx






chishingchan 发表于 2020-7-19 09:38:10

guland 发表于 2020-7-17 08:36
这个应该可以

论坛的 BUG:
winmgmts:\应为 winmgmts:\\

afan 发表于 2020-7-17 13:54:26

依旧漂泊 发表于 2020-7-16 20:30
向上兼容?是什么意思?
编译一份64位的FileInstall进32位,相对比较麻烦。我的意思是编译成32位版本可 ...

32位程序获取64位程序进程信息,相当于向上兼容了
GetModuleFileNameEx 是不支持的,除非你打个64的包试试~

或者调用其他兼容的 api,比如 QueryFullProcessImageName 或者 GetProcessImageFileName 等

guland 发表于 2020-7-17 08:36:56

这个应该可以

Dim $name="ctfmon.exe"
__wmi_Win32_Process()
Func __wmi_Win32_Process()
        Local $wbemFlagReturnImmediately = 0x10
        Local $wbemFlagForwardOnly = 0x20
        Local $colItems = ""
        Local $strComputer = "localhost"
        Local $Output=""
        Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
        $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process where Name='"&$name&"'", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
        If IsObj($colItems) then
           For $objItem In $colItems
              $Output &= "ExecutablePath: " & $objItem.ExecutablePath & @CRLF
              $Output &= "Name: " & $objItem.Name & @CRLF
       Next
       Msgbox(0,"WMI 输出",$Output )
        Else
           Msgbox(0,"WMI 输出","没有在类 " & "Win32_Process" & "中找到WMI对象" )
        Endif
EndFunc

floor6ggg 发表于 2020-7-16 15:59:26

试一试,首行加上:
#PRE_Compile_Both=y
看看行不行

依旧漂泊 发表于 2020-7-16 16:30:26

floor6ggg 发表于 2020-7-16 15:59
试一试,首行加上:

看看行不行


现在,这么说吧,64位系统用X64版本能正常获取 explorer.exe 进程的路径,
用X86版本获取不到 explorer.exe 进程的路径

afan 发表于 2020-7-16 19:38:16

你这是想向上兼容?。。。
编译一份64位的FileInstall进32位~

依旧漂泊 发表于 2020-7-16 20:30:39

本帖最后由 依旧漂泊 于 2020-7-16 20:32 编辑

afan 发表于 2020-7-16 19:38
你这是想向上兼容?。。。
编译一份64位的FileInstall进32位~
向上兼容?是什么意思?
编译一份64位的FileInstall进32位,相对比较麻烦。我的意思是编译成32位版本可以获取32位进程路径,无法获取64位进程路径的问题
反之编译成64位版本可以获取32位与64位进程路。

依旧漂泊 发表于 2020-7-18 03:41:09

afan 发表于 2020-7-17 13:54
32位程序获取64位程序进程信息,相当于向上兼容了
GetModuleFileNameEx 是不支持的,除非你打个64的包试 ...

谢谢,请问下这两个函数在哪里查,帮忙文档没有看到。

afan 发表于 2020-7-18 10:25:04

帮助文档没有,可以查阅以下,调用方式都是大同小异
https://docs.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-queryfullprocessimagenamea
https://docs.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-getprocessimagefilenamea
页: [1]
查看完整版本: 通过进程名获取进程路径[已解决]