Get File Path from Window Handle
Posted: Sat Jul 16, 2011 12:35 pm
All I wanted to do was to get the path of the file which launched a window. In Windows 2000 and before it's easy - you use GetModuleFileName, and in Vista and after it's also easy - you use QueryFullProcessImageName. But for Windows Xp you need this:
There are two things I would be interested in knowing the answer to
(1) Does it also run under Windows 7?
(2) The call to GetProcessImageFileNameA returns more data than you want (ReturnValue gives the length). Because the date you do want is null-terminated the ImageName variable gives the correct string. However, does the bit after the null get "Lost in Space"?
Code: Select all
;References: http://msdn.microsoft.com/en-us/library/ms683217 (GetProcessImageFileName Function)
; http://msdn.microsoft.com/en-us/library/aa364975%28VS.85%29.aspx (GetLogicalDriveStrings Function)
; http://msdn.microsoft.com/en-us/library/aa365461%28VS.85%29.aspx (QueryDosDevice Function)
EnableExplicit
Procedure.s GetPathFromHwnd(theHwnd)
Protected ProcessId.l, ReturnValue.l, hProcess.l, ImageName.s, Dim AllDriveStringsArray.b(512)
Protected Nsize.l, Inc.l, AllDriveStrings.s, DeviceStr.s
Protected TargetPath.s, Lib.l, *pAfunc.l, DriveStringsLen.l, Counter.l
Nsize = 512
ReturnValue = GetWindowThreadProcessId_(theHwnd, @ProcessId)
If ProcessId <> 0
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION, #False, ProcessId)
If hProcess <> 0
Lib = LoadLibrary_("psapi.dll")
If Lib
ImageName = Space(Nsize)
*pAfunc = GetProcAddress_(Lib, "GetProcessImageFileNameA")
Returnvalue = CallFunctionFast(*pAfunc,hProcess, @ImageName, Nsize) ; returns the path in device format
FreeLibrary_(Lib)
EndIf
If ReturnValue <> 0
DriveStringsLen = GetLogicalDriveStrings_(Nsize, @AllDriveStringsArray(0))
If ReturnValue <> 0
Repeat
DeviceStr = ""
Repeat
If AllDriveStringsArray(Counter) <> 0
DeviceStr = DeviceStr + Chr(AllDriveStringsArray(Counter))
Counter = Counter + 1
Else
Break
EndIf
ForEver
Counter = Counter + 1
If Right(DeviceStr, 1) = "\"
DeviceStr = Left(DeviceStr, Len(DeviceStr) - 1)
EndIf
TargetPath = Space(Nsize)
ReturnValue = QueryDosDevice_(@DeviceStr, @TargetPath, Nsize)
If Left(ImageName, Len(TargetPath)) = TargetPath
ProcedureReturn ReplaceString(ImageName, TargetPath, DeviceStr)
EndIf
Until Counter >= DriveStringsLen
EndIf
EndIf
CloseHandle_(hProcess)
EndIf
EndIf
EndProcedure
RunProgram("C:\WINDOWS\system32\calc.exe")
Delay(1000)
Debug GetPathFromHwnd(FindWindow_("SciCalc", "Calculator"))
(1) Does it also run under Windows 7?
(2) The call to GetProcessImageFileNameA returns more data than you want (ReturnValue gives the length). Because the date you do want is null-terminated the ImageName variable gives the correct string. However, does the bit after the null get "Lost in Space"?