by willsteele at 2012-08-22 14:52:53
I am experimenting with some Win32 P/Invoke functions. I have the following command to generate a new type so I can call the GetForegroundWindow of the User32 .dll. When it runs I get a handle back, but, it does not correspond with the handle I get when I run Get-Process for the active window. Is there a way I might translate this handle value to something I can use based on the publically exposed handles shown for processes as returned via the Get-Process cmdlet?
$signature_Win32_GetForegroundWindow = @"
public static extern IntPtr GetForegroundWindow();
$Win32API = Add-Type -MemberDefinition $signature_Win32_GetForegroundWindow `
-Namespace Windows `
-Name Win32 `
When I run it it returns 1643092. Using the $PID built-in variable I get this: 9904. Furthermore, I check the threads in my process but none of these really correlate with my return value:
Get-Process -pid $pid | select -ExpandProperty Threads | select startaddress,id
I know this is a little out there, but, I wanted to see how I could connect the dots with these internal addresses to Process ID values.
by MattG at 2012-08-22 18:32:52
You're talking about two different things. Your Get-Process command isn't returning handles, rather it's returning the thread IDs and the addresses from which they were started. Note that the thread with a StartAddress of zero is the main thread of execution that was started when the process was loaded.
Assuming there is only one graphical window present, which should be the case with PowerShell, [Windows.Win32]::GetForegroundWindow() and (Get-Process -pid $pid).MainWindowHandle should yield that same value. I just confirmed this to be the case on my instance of PS with your code. The only time where this shouldn't be the case is obviously if you have more then one window for a single process.
For a good primer on handles, this blog post from Mark Russinovich is invaluable.
by willsteele at 2012-08-22 19:09:05
Ok, thanks Matt. That makes sense. So, what is the value returned by the GetForegroundWindow? I presume its a virtual memory address. Is that correct? Is it relative to the virtual address space of the process or the full memory address space?
Also, I guess this thread belongs more in the developers forum. If any of the admins want to move it, feel free to relocate it. I thought I was focusing on scripting, but, this is probably going to be a dev-centric thread.
by MattG at 2012-08-23 02:51:21
While the value returned is of the IntPtr type, it isn't actually a virtual address. Rather, it's an index into the kernel handle table. To see this first hand, download Process Explorer, click on any process, click 'View Handles (Ctrl+H)', and enable the 'Handle Value' and 'Object Address' columns. You'll see that each handle (or index) points to kernel memory. handles.exe, which is part of Sysinternals is also a handy tool. It needs to be run from an elevated command prompt.