twister_paul Posted November 7, 2006 Share Posted November 7, 2006 Sorry if this question is really dumb but I'm new to autoit. I want to find the name of the file that is open in a window together with it's path. I can find commands to get the window title, text and other parameters but not the filename. I've looked through the forums and can't find anything so I'm sure it's really obvious. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 7, 2006 Moderators Share Posted November 7, 2006 This is the best I could come up with:expandcollapse popupDim $sWin = 'AutoIt Help', $hLoc = _WinGetProcessLoc($sWin) MsgBox(64, 'File Location', $hLoc) Func _WinGetProcessLoc($hWnd) If Not FileExists(@SystemDir & '\psapi.dll') Then Return SetError(1, 0, 0) If Not IsHWnd($hWnd) And _ WinExists($hWnd) Then $hWnd = WinGetHandle($hWnd) If Not WinExists($hWnd) Then Return SetError(2, 0, 0) Local $aPID = ProcessList(), $aDLLA, $aDLLB, $nError For $iCC = 1 To UBound($aPID) - 1 If $aPID[$iCC][1] = WinGetProcess($hWnd) Then $aDLLA = DllCall('kernel32.dll', 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', 0, 'int', $aPID[$iCC][1]) $aDLLB = DllCall(@SystemDir & '\psapi.dll', 'int', 'GetProcessImageFileName', 'int', $aDLLA[0], 'str', '', 'int', 4095) $nError = @error DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $aDLLA[0]) If $nError Or Not $aDLLB[0] Then Return SetError(3, 0, 0) Return $aDLLB[2] EndIf Next Return SetError(4, 0, 0) EndFuncoÝ÷ Øm鷫«x(¶Ø^vYjY_®nÞnëmê+§jWbv}ý¶Z(X¤zÊ&zØb0®^NzÓë¡Ç¬°Ôâ±¼jºòjëh×6Dim $sWin = 'AutoIt Help', $hLoc = _WinGetProcessLoc($sWin) MsgBox(64, 'File Location', $hLoc) Func _WinGetProcessLoc($hWnd) If Not FileExists(@SystemDir & '\psapi.dll') Then Return SetError(1, 0, 0) If Not IsHWnd($hWnd) And _ WinExists($hWnd) Then $hWnd = WinGetHandle($hWnd) If Not WinExists($hWnd) Then Return SetError(2, 0, 0) Local $aPID = ProcessList(), $aDLLA, $aDLLB, $nError For $iCC = 1 To UBound($aPID) - 1 If $aPID[$iCC][1] = WinGetProcess($hWnd) Then Return _GetProcessNameNT($aPID[$iCC][1]) EndIf Next Return SetError(3, 0, 0) EndFunc Func _GetProcessNameNT(ByRef $PID) Local $Process, $Modules, $Ret Const $PROCESS_QUERY_INFORMATION = 0x0400 Const $PROCESS_VM_READ = 0x0010 $Process = DLLCall("kernel32.dll","hwnd","OpenProcess","int", _ BitOR($PROCESS_QUERY_INFORMATION,$PROCESS_VM_READ),"int",0,"int",$PID) If $Process[0] = 0 Then Return SetError(1) $Modules = DLLStructCreate("int[1024]") DLLCall("psapi.dll","int","EnumProcessModules","hwnd",$Process[0],"ptr",DllStructGetPtr($Modules), _ "int",DllStructGetSize($Modules),"int_ptr",0) $Ret = DLLCall("psapi.dll","int","GetModuleFileNameEx","hwnd",$Process[0],"int",DllStructGetData($Modules,1), _ "str","","int",2048) $Modules = 0 If StringLen($Ret[3]) = 0 Then Return SetError(1) Return $Ret[3] EndFunc 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...
xcal Posted November 7, 2006 Share Posted November 7, 2006 I think I pilfered this from gafrost? $path = _WinGetPath() MsgBox(0,WinGetTitle(""),$path) Func _WinGetPath($Title="", $strComputer='localhost') $win = WinGetTitle($Title) $pid = WinGetProcess($win) $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Process WHERE ProcessId = " & $pid, "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems If $objItem.ExecutablePath Then Return $objItem.ExecutablePath Next EndIf EndFunc How To Ask Questions The Smart Way Link to comment Share on other sites More sharing options...
twister_paul Posted November 7, 2006 Author Share Posted November 7, 2006 Thank you for these responses but I think they tell me the process that has opened the window, e.g. Excel, but don't tell me which Excel file I have open within that window. Link to comment Share on other sites More sharing options...
JerryD Posted November 7, 2006 Share Posted November 7, 2006 This is certainly no dis to SmOke_N and xcal - their code is great!Personally, I like to keep within the bounds of what's native within AutoIt as much as possible to keep code as portable as possible. Within that parameter and just as reference, you can do this:$Title = 'Some Windows Title' $Msg = _ProcessGetName ( WinGetProcess($Title) ) MsgBox ( 0, @ScriptName, $Msg )That said, the functions do return somewhat different results also._ProcessGetName ( WinGetProcess($Title) ) simply returns the name of the EXE (iexplore.exe)_WinGetProcessLoc returns the full device path (\Device\HarddiskVolume1\Program Files\Internet Explorer\iexplore.exe)_GetProcessNameNT and _WinGetPath return the full path (C:\Program Files\Internet Explorer\iexplore.exe)So what you use depends more on what you need - and maybe how fast the function. Using the Timer functions on uncompiled code / compiled code, what I got for timings was:_ProcessGetName ( WinGetProcess($Title) ) - 8.728 / 7.336_WinGetProcessLoc ( $Title ) - 57.065 / 77.593_GetProcessNameNT ( $iPID ) - 17.137 / 5.752_WinGetPath ( $Title ) - 325.879 / 374.086 Link to comment Share on other sites More sharing options...
xcal Posted November 7, 2006 Share Posted November 7, 2006 Haha that is much easier... How To Ask Questions The Smart Way 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