Trong Posted March 1, 2015 Share Posted March 1, 2015 Function below is not working, Any ideas! DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 1) expandcollapse popup; #FUNCTION# =============================================================================== ; Name...........: _ProcessGetPath() ; Description ...: Retrieves a process file path ; Syntax.........: _ProcessGetPath($vProcess) ; Parameters ....: $vProcess - PID or name of a process ; Requirements...: kernel32.dll, psapi.dll ; Return values .: Success - A full process path ; @error = 0 ; Failure - Empty string ; @error = 1 - Invalid process name/PID ; @error = 2 - kernel32.dll failed to open (wrong version?) ; @error = 3 - Could not OpenProcess ; @error = 4 - psapi.dll failed to open (doesn't exist?) ; @error = 5 - returned path is empty or invalid ; Author ........: JScript, Larry, SmOke_N ; Modified.......: mrRevoked - reformated, error checking : Trong - fix special path ; Example .......: Yes ; ============================================================================================ Func _ProcessGetPath($vProcess) Local $i_PID, $hKernel32, $hPsapi, $aProcessHandle, $tDLLStruct, $iError, $sProcessPath $i_PID = ProcessExists($vProcess) If Not $i_PID Then Return SetError(1, 0, ""); Process doesn't exist? $hKernel32 = DllOpen("Kernel32.dll") $iError = @error If $iError Then DllClose($hKernel32) Return SetError(2, $iError, ""); DllOpen kernell32.dll failed EndIf $aProcessHandle = DllCall($hKernel32, "int", "OpenProcess", "int", 0x0400 + 0x0010, "int", 0, "int", $i_PID) $iError = @error If $iError Or $aProcessHandle[0] = 0 Then DllClose($hKernel32) Return SetError(2, $iError, ""); OpenPocess failed EndIf $hPsapi = DllOpen("Psapi.dll") $iError = @error If $iError Then DllClose($hKernel32) DllClose($hPsapi) Return SetError(3, $iError, ""); DllOpen psapi.dll failed EndIf $tDLLStruct = DllStructCreate("char[1000]") DllCall($hPsapi, "long", "GetModuleFileNameEx", "int", $aProcessHandle[0], "int", 0, "ptr", DllStructGetPtr($tDLLStruct), "long", DllStructGetSize($tDLLStruct)) $iError = @error DllCall($hKernel32, "int", "CloseHandle", "int", $aProcessHandle[0]) DllClose($hKernel32) DllClose($hPsapi) If $iError Then $tDLLStruct = 0 Return SetError(4, $iError, "");GetModulefilenamex failed EndIf $sProcessPath = DllStructGetData($tDLLStruct, 1) $tDLLStruct = 0 ;Format the Output If StringLen($sProcessPath) < 2 Then Return SetError(5, 0, "");is empty or non readable If StringLeft($sProcessPath, 4) = "\??\" Then $sProcessPath = StringReplace($sProcessPath, "\??\", "") If (StringLower(StringLeft($sProcessPath, 20)) = "\systemroot\system32") Then $sProcessPath = StringReplace($sProcessPath, "\SystemRoot\System32", @SystemDir) Return SetError(0, 0, $sProcessPath) EndFunc ;==>_ProcessGetPath ; * -----:| ===================================================================================================================== Regards, Link to comment Share on other sites More sharing options...
Moderators Solution SmOke_N Posted March 1, 2015 Moderators Solution Share Posted March 1, 2015 (edited) That's not a good way to get the process path, but anyway... what is your error (number). Edit: Here's a processgetpath i wrote that should work with everything. expandcollapse popup#include <WinAPI.au3> #include <WinAPIProc.au3> ; @param1 = process name or pid ; @param2 = default 0 = drive\etc format ; true = native system path format Func _ProcessGetPathEx($vProcess, $bNative = 0) Local $iPID = ProcessExists($vProcess) If Not $iPID Then ; process does not exist Return SetError(1, 0, "") EndIf Local $szFilePath = "" ; are we working with anything less than vista? Local Static $nWVers = ($__WINVER <> "") ? $__WINVER : __WINVER() If $nWVers < 0x0600 Then ; _WinAPI_GetProcessFileName seems misleading $szFilePath = _WinAPI_GetProcessFileName($iPID) Return SetError(@error, @extended, $szFilePath) EndIf ; vista and above, should help with possible 64bit issues as well Local $hK32 = DllOpen("Kernel32.dll") If @error Or Not $hK32 Then ; could not open kernel32.dll Return SetError(2, 0, 0) EndIf Local Const $pgp_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 Local Const $pgp_PROCESS_QUERY_INFORMATION = 0x0400 Local Const $pgp_PROCESS_NAME_NATIVE = 0x00000001 ; open process with query info only Local $aOpenProcess = DllCall($hK32, "handle", "OpenProcess", _ "long", BitOR($pgp_PROCESS_QUERY_INFORMATION, _ $pgp_PROCESS_QUERY_LIMITED_INFORMATION), _ "int", 0, "long", $iPID) Local $iErr = @error If $iErr Or Not IsArray($aOpenProcess) Then DllClose($hK32) ; error code from dllcall sent as extended Return SetError(3, $iErr, 0) EndIf Local $hOpenProc = $aOpenProcess[0] Local $nNative = $bNative ? $pgp_PROCESS_NAME_NATIVE : 0 Local $aQuery = DllCall($hK32, "bool", "QueryFullProcessImageNameW", _ "handle", $hOpenProc, "dword", $nNative, "wstr", "", "int*", 4096) $iErr = @error If $iErr Or Not IsArray($aQuery) Then _WinAPI_CloseHandle($hOpenProc) DllClose($hK32) ; error code from dllcall sent as extended Return SetError(4, $iErr, 0) EndIf _WinAPI_CloseHandle($hOpenProc) DllClose($hK32) ; return string length as extended Return SetError(0, $aQuery[4], $aQuery[3]) EndFunc ;==>_ProcessGetPathEx And as always, if it's not working, show the error number you've debugged and received. Edited March 1, 2015 by SmOke_N Trong 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Trong Posted March 1, 2015 Author Share Posted March 1, 2015 Thanks SmOke_N! Need edit itLocal $iPid0 = Run("notepad.exe") ; WinWait("[CLASS:Notepad]", "", 10) ConsoleWrite('"Notepad.exe" PID = ' & $iPid0 & @CRLF) Local $sNotepad = "notepad.exe" Local $sReturn = _ProcessGetPathEx($sNotepad) ConsoleWrite("@error:"&@error & " @extended:" &@extended &" Return:"&$sReturn&@CRLF) ProcessClose("notepad.exe") Local $iPid0 = Run("C:\Windows\SysWOW64\notepad.exe") ; WinWait("[CLASS:Notepad]", "", 10) ConsoleWrite('"Notepad.exe" PID = ' & $iPid0 & @CRLF) Local $sNotepad = "notepad.exe" Local $sReturn = _ProcessGetPathEx($sNotepad) ConsoleWrite("@error:"&@error & " @extended:" &@extended &" Return:"&$sReturn&@CRLF) ProcessClose("notepad.exe") Local $iPid0 = Run("C:\Windows\System32\notepad.exe") ; WinWait("[CLASS:Notepad]", "", 10) ConsoleWrite('"Notepad.exe" PID = ' & $iPid0 & @CRLF) Local $sNotepad = "notepad.exe" Local $sReturn = _ProcessGetPathEx($sNotepad) ConsoleWrite("@error:"&@error & " @extended:" &@extended &" Return:"&$sReturn&@CRLF) ProcessClose("notepad.exe") Local $iPid0 = Run("C:\Windows\Sysnative\notepad.exe") ; WinWait("[CLASS:Notepad]", "", 10) ConsoleWrite('"Notepad.exe" PID = ' & $iPid0 & @CRLF) Local $sNotepad = "notepad.exe" Local $sReturn = _ProcessGetPathEx($sNotepad) ConsoleWrite("@error:"&@error & " @extended:" &@extended &" Return:"&$sReturn&@CRLF) ProcessClose("notepad.exe") ProcessClose("notepad.exe") "Notepad.exe" PID = 328 @error:0 @extended:52 Return:\Device\HarddiskVolume1\Windows\SysWOW64\notepad.exe "Notepad.exe" PID = 5536 @error:0 @extended:52 Return:\Device\HarddiskVolume1\Windows\SysWOW64\notepad.exe "Notepad.exe" PID = 4020 @error:0 @extended:52 Return:\Device\HarddiskVolume1\Windows\SysWOW64\notepad.exe "Notepad.exe" PID = 5380 @error:0 @extended:52 Return:\Device\HarddiskVolume1\Windows\System32\notepad.exe Regards, Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 2, 2015 Moderators Share Posted March 2, 2015 I don't know if you're asking me a question, if something is wrong, or if it solved the issue. If the path is incorrect or not what you expected, look at the second parameter of my function. _ProcessGetPathEx($sNotepad) Gives a different result on the path than: _ProcessGetPathEx($sNotepad, True) Trong 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Trong Posted March 2, 2015 Author Share Posted March 2, 2015 _ProcessGetPathEx($sNotepad) If Notepad.exe*32 Then C:\Windows\System32\notepad.exe _ProcessGetPathEx($sNotepad, True) /_ProcessGetPathEx($sNotepad, 1) If Notepad.exe*64 Then DeviceHarddiskVolume1WindowsSystem32notepad.exe Regards, Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now