Ármányos Kő Posted February 9, 2008 Posted February 9, 2008 Hi, I have an au3 automation toolbar working with Adobe FrameMaker7.2 and FrameMaker 8.0. Users may use any of the two, but some things must be automated differently in the two versions. How can I get the full path to the exe when the user hits one button in one of the version? The path would tell whether it is 7.2 or 8.0.
Bowmore Posted February 9, 2008 Posted February 9, 2008 Hi, I have an au3 automation toolbar working with Adobe FrameMaker7.2 and FrameMaker 8.0. Users may use any of the two, but some things must be automated differently in the two versions. How can I get the full path to the exe when the user hits one button in one of the version? The path would tell whether it is 7.2 or 8.0. This should work for most processes, (There may be a few that windows will not allow access to) It uses GetModuleFileNameEx() from Psapi.dll #include <WinAPI.au3> $Process = "lsass.exe" ; This is just an example application $FullPath = _GetProcPath($Process) MsgBox(0, "Process Full Path", "Process = " & $Process & @CRLF _ & "Path = " & $FullPath) Func _GetProcPath($Process_In) Local $iProc, $hModule, $hProc, $stString, $iResult, $sPath $iProc = ProcessExists($Process) $hModule = 0 $hProc = _WinAPI_OpenProcess(BitOR(0x0400, 0x0010), False, $iProc) $stString = DllStructCreate("char[260]") $iResult = DllCall("Psapi.dll", "dword", "GetModuleFileNameEx", _ "hwnd", $hProc, _ "hwnd", $hModule, _ "ptr", DllStructGetPtr($stString), _ "dword", 260) $sPath = DllStructGetData($stString, 1) Return $sPath EndFunc ;==>_GetProcPath "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook
rover Posted February 10, 2008 Posted February 10, 2008 (edited) tested with notepad.exe in 2 folder locationsexe path returned for currently active windowEdit: Feb 13 - fixed missing additional close open handle calls, changed error handling slightlyexpandcollapse popupOpt("MustDeclareVars", 1) ;Local $ret = _GetActiveWinEXEPath("FrameMaker.exe", "FrameMaker");Match any substring in the title Local $ret = _GetActiveWinEXEPath("notepad.exe", "Notepad") ConsoleWrite('-> ExecutablePath: ' & $ret & @CRLF & "-> Error: " & @error & @CRLF) Func _GetActiveWinEXEPath($filename, $title = ""); filename and title substring(optional) ; Returns the executable path of the active program window ; where more than one instance of program with same exe name is running. ; Parameters: ; $filename = Executable name, i.e "notepad.exe" without path ; $title = substring of window title, i.e. "Notepad" or "Untitled" ; Return: ; On Success: Exe path of active window and @error set to 0 ; On Error: "" and @error set to 1 ; large chunk of code in this script from post by PerryRaptor ; code from this post nicely replaces my WMI code in first version ; http://www.autoitscript.com/forum/index.php?showtopic=56280 Local $hWnd, $aWinList, $aProcList, $mode, $pid, $hProc, $stHMod, $stCB, $resEnum, $resPath, $err If Not ProcessExists($filename) Then SetError(1) Return "" EndIf $mode = Opt("WinTitleMatchMode", 2) ; Match any substring in the title If $title <> "" Then $aWinList = WinList($title, "") Else $aWinList = WinList() EndIf Opt("WinTitleMatchMode", $mode) $aProcList = ProcessList($filename) For $i1 = 1 To $aWinList[0][0] If $aWinList[$i1][0] <> "" Then For $i2 = 1 To $aProcList[0][0] $pid = $aProcList[$i2][1] $hProc = DllCall("kernel32.dll", "int", "OpenProcess", "int", _ 0x0410, "int", False, "int", $pid) $err = @error If $err Then If $hProc[0] Then DllCall("kernel32.dll", 'int', 'CloseHandle', 'int', $hProc[0]) SetError($err, @extended, 0) Return "" EndIf If $hProc[0] Then $stHMod = DllStructCreate("int hMod") $stCB = DllStructCreate("dword cbNeeded") $resEnum = DllCall("psapi.dll", "int", "EnumProcessModules", _ "int", $hProc[0], "ptr", DllStructGetPtr($stHMod), "dword", _ DllStructGetSize($stHMod), "ptr", DllStructGetPtr($stCB, 1)) $err = @error If $err Then DllCall("kernel32.dll", 'int', 'CloseHandle', 'int', $hProc[0]) SetError($err, @extended, 0) Return "" EndIf If $resEnum[0] Then $resPath = DllCall("psapi.dll", "int", "GetModuleFileNameEx", _ "int", $hProc[0], "int", DllStructGetData($stHMod, 1), _ "str", "", "dword", 32768) $err = @error DllCall("kernel32.dll", 'int', 'CloseHandle', 'int', $hProc[0]) If $err Then SetError($err, @extended, 0) Return "" EndIf If WinGetProcess($aWinList[$i1][1]) = $pid Then $hWnd = $aWinList[$i1][1] If BitAND(WinGetState($hWnd, ""), 8) Then If FileExists($resPath[3]) Then SetError(0) Return $resPath[3] Else SetError(1) Return "" EndIf EndIf EndIf EndIf $stHMod = 0 $stCB = 0 If $hProc[0] Then DllCall("kernel32.dll", 'int', 'CloseHandle', 'int', $hProc[0]) If @error Then SetError(@error, @extended, 0) Return "" EndIf EndIf Next EndIf Next SetError(1) Return "" EndFunc ;==>_GetActiveWinEXEPath Edited February 13, 2008 by rover I see fascists...
rover Posted February 10, 2008 Posted February 10, 2008 WMI version expandcollapse popup; requires WMI service running ; Win32_Process Class Requires Windows Vista, Windows XP, ; Windows 2000 Professional, or Windows NT Workstation 4.0 SP4 and later. Opt("MustDeclareVars", 1) Local $ret = _GetActiveWinEXEPath("FrameMaker.exe", "FrameMaker");Match any substring in the title ;Local $ret = _GetActiveWinEXEPath("notepad.exe", "Notepad") ConsoleWrite('-> ExecutablePath: ' & $ret & @CRLF & "-> Error: " & @error & @CRLF) Global $oMyError Func _GetActiveWinEXEPath($filename, $title = ""); filename and title substring(optional) ; Returns the executable path of the currently active window of a program ; where one or more versions of program with same exe name are running. ; Parameters: ; $filename = Executable name, i.e "notepad.exe" without path ; $title = substring of window title, i.e. "Notepad" or "Untitled" ; Return: ; On Success: Exe path of active window and @error set to 0 ; On Error: "" and @error set to 1 Local $colItems = "", $hWnd, $objWMIService, $aWinList, $mode Local $strComputer = "localhost" ; or "." or @Computername Local $strQuery = "SELECT ExecutablePath,ProcessId FROM Win32_Process WHERE Name = '" Local $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") If Not ProcessExists($filename) Then SetError(1) Return "" EndIf ;$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2") If Not IsObj($objWMIService) Or @error = 1 Then SetError(1) ; Error connecting to WMI Return "" EndIf $mode = Opt("WinTitleMatchMode", 2) ; Match any substring in the title If $title <> "" Then $aWinList = WinList($title, "") Else $aWinList = WinList() EndIf Opt("WinTitleMatchMode", $mode) $colItems = $objWMIService.ExecQuery($strQuery & $filename & "'", "WQL", 0x30) If IsObj($colItems) Then For $objItem In $colItems If IsObj($objItem) Then For $i = 1 To $aWinList[0][0] If $aWinList[$i][0] <> "" Then If WinGetProcess($aWinList[$i][1]) = $objItem.ProcessId Then $hWnd = $aWinList[$i][1] ExitLoop EndIf EndIf Next If BitAND(WinGetState($hWnd, ""), 8) Then If FileExists($objItem.ExecutablePath) Then SetError(0) Return $objItem.ExecutablePath Else SetError(1) Return "" EndIf EndIf EndIf Next EndIf SetError(1) Return "" EndFunc ;==>_GetActiveWinEXEPath Func MyErrFunc() Local $HexNumber = Hex($oMyError.number,8) ConsoleWrite("Debug: Intercepted COM Error: Number = " & $HexNumber & _ " Windescription = " & $oMyError.windescription & @LF) SetError(1) Return 0 Endfunc I see fascists...
Ármányos Kő Posted February 10, 2008 Author Posted February 10, 2008 Hi,I have an au3 automation toolbar working with Adobe FrameMaker7.2 and FrameMaker 8.0.Users may use any of the two, but some things must be automated differently in the two versions. How can I get the full path to the exe when the user hits one button in one of the version?The path would tell whether it is 7.2 or 8.0.You guys seem unstoppable!Thanks for the versions.I will test them and use one.I now have some rude code, popping the menu and sensing what happens and deciding which version the software is...Yours seem far better....
Ascend4nt Posted February 20, 2009 Posted February 20, 2009 Other alternatives:_WinAPI_ProcessGetFileName() and _WinAPI_ProcessGetPathname() My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code)
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