Find process associated with window
Is there any way in NSIS to find out the ProcessID (and/or ProcessName) associated with a particular window returned by FindWindow?
Archive: Find process associated with window
Find process associated with window
Is there any way in NSIS to find out the ProcessID (and/or ProcessName) associated with a particular window returned by FindWindow?
If you use the system plugin to call FindWindowEx you will get a handle to your window and then you can use GetWindowThreadProcessId to get the thread and/or process ID that created the window or GetWindowModuleFilename to get the filename of the process that created the window.
Hope this helps
CF
Thanks CancerFace,
I've tried to do that with some success, however, I'm getting stuck with something weird.
The following section loops through all the windows, and lists the window title, window handle, class name, filename, thread id and process id.
Title, handle and thread id are working perfectly.
For some reason I fail to understand though, I get no process id (it returns 0 every time) and the filename is rather random (most of the time it returns the filename of the installer itself).
I'm a bit lost...Section "ListWindowsInfo"
::Get "(i.r1, i) iss"
FileOpen $8 "c:\temp\windowslist.txt" "w"
SetPluginUnload alwaysoff
System
Pop $R0
System::Call "user32::EnumWindows(k R0, i) i.s"
loop:
Pop $0
StrCmp$0 "callback1" 0 done
System::Call "user32::GetWindowText(ir1,t.r2,i${NSIS_MAX_STRLEN})"
System::Call "user32::GetClassName(ir1,t.r3,i${NSIS_MAX_STRLEN})"
System::Call "user32::GetWindowModuleFileName(ir1,t.r6,i${NSIS_MAX_STRLEN})"
System::Call "user32::GetWindowThreadProcessId(ir1,i.r7) i .r9"
IntFmt $4 "0x%X" $1
FileWrite$8 "$1 / $4 - ***91;$3***93; $2$\r$\n"
FileWrite $8 " $1 -->> FileName: $6$\r$\n"
FileWrite $8 " $1 -->> Thread: $9$\r$\n"
FileWrite $8 " $1 -->> Process: $7$\r$\n"
Push 1 # callback's return value
System::Call "$R0"
Goto loop
done:
SetPluginUnload manual
System::Free $R0
FileClose$8
SectionEnd
>
Strange, although the threads are picked it seems that the process is always 0. However the filename is not always the name of the NSIS script, there are some instances of comctl32.dll. I have no clue why!
The only thing I managed to dig out is this:
GetWindowModuleFileName returns the name of a EXE or DLL that created a window. Be forewarned though; this API only works on HWNDs created by the process that called the API. This means it’s only of use for windows that your program created or within a systemwide hook procedure.and I wonder if this is the reason for the above behavior
Originally posted by CancerFaceI found that one, I should have used a pointer:
Strange, although the threads are picked it seems that the process is always 0.
System::Call "user32::GetWindowThreadProcessId(ir1,*i.r7) i .r9"
However the filename is not always the name of the NSIS script, there are some instances of comctl32.dll. I have no clue why!I read the same thing and will have to agree with you on that one.
The only thing I managed to dig out is this:
and I wonder if this is the reason for the above behavior
You can use GetModuleFileNameEx to get the executable name for a process other than yours. This could explain why you keep getting the installer's executable name. This function is only supported on Windows NT or later and you need the PSAPI library (see below).
The ToolHelper functions are only viable under Windows 98/95. They were removed in NT and later, replaced with PSAPI functions/libraries. NT does not have the PSAPI library included by default, you can copy the PSAPI.DLL from Windows XP into a directory on the path and use it if you want, otherwise grab the installer from Microsoft.
I am not very familiar with the thread-to-window association stuff, sorry I can't help with that yet.
Duncan
That's a good idea Mr Inches :)
I think this should work:
Section "ListWindowsInfo"
FileOpen $8 "c:\tempwindowslist.txt" "w"
SetPluginUnload alwaysoff
System::Get "(i.r1, i) iss"
Pop $R0
System::Call "user32::EnumWindows(k R0, i) i.s"
loop:
Pop $0
StrCmp $0 "callback1" 0 done
System::Call 'user32::GetWindowText(ir1,t.r2,i${NSIS_MAX_STRLEN})i.R6'
System::Call 'user32::GetClassName(ir1,t.r3,i${NSIS_MAX_STRLEN})i.R6'
System::Call 'user32::GetWindowThreadProcessId(ir1,*i.r7)i.r9'
System::Call 'kernel32::OpenProcess(i 0x1F0FFF,i0,ir7)i.R9'
System::Call 'Psapi::GetModuleFileNameExA(iR9,in,t.R8,i${NSIS_MAX_STRLEN})i.R6'
System::Call 'kernel32::CloseHandle(iR9)i.R6'
IntFmt $4 "0x%X" $1
FileWrite $8 "$1 / $4 - [$3] $2$\r$\n"
FileWrite $8 " $1 -->> Thread: $9$\r$\n"
FileWrite $8 " $1 -->> Process: $7$\r$\n"
FileWrite $8 " $1 -->> FileName: $R8$\r$\n"
Push 1 # callback's return value
System::Call "$R0"
Goto loop
done:
SetPluginUnload manual
System::Free $R0
FileClose $8