improve.dk
Just another mindless drone looking for the perfect stack
posts - 227, comments - 489

Getting a process from a handle

Written on April 3, 2007 by Mark S. Rasmussen in Development: .NET, Development: Win32

So we have a handle, what process does it belong to? Our goal is to obtain a .NET System.Diagnostics.Process object that corresponds to the owner process of the handle we input.

Let's first open up an Internet Explorer window, just leave it at the start page, whatever yours is.

win32_1_1

Now fire up Winspector and locate the Internet Explorer window, you'll see the handle in HEX format in the treeview.

win32_1_2

using System;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Diagnostics;

namespace Get_process_from_handle
{
	class Program
	{
		// The DllImport attribute specifies the Win32 DLL that contains the function we're importing,
		// in this case it's the user32.dll file that resides in the C:\Windows\System32 directory.
		// The function we're importing is GetWindowThreadProcessId, it takes a handle and a reference
		// to an outgoing integer that'll return the process ID of the handle.
		[DllImport("user32")]
		public static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

		static void Main(string[] args)
		{
			// First, read the handle from the console, remember this has to be in HEX format!
			int handle = int.Parse(Console.ReadLine(), NumberStyles.HexNumber);

			// Now that we have the handle, create an uninitialized integer that'll hold the process ID
			// of the handle process.
			int processID;
			GetWindowThreadProcessId(handle, out processID);

			// Now that we have the process ID, we can use the built in .NET function to obtain a process object.
			Process p = Process.GetProcessById(processID);

			// Finally we'll write out the process name to confirm success.
			Console.Write(p.ProcessName);
			Console.Read();
		}
	}
}

And the result:

win32_1_3

Feedback

Gravatar

Thorsten Lorenz wrote on 1/22/2009 11:54 PM

You keep using (int) types to pass parameters and receive results a lot of times during this blog series, which is great by the way.
Shouldn't it be (InPtr) most of the time?
Like here:
www.pinvoke.net/.../user32.SendMessage<br
The reason I'm asking is because I used what I learned from you blog and implemented a windows finder but the application sometimes hangs itself at this line:
txtLength = (int) User32.SendMessage(handle, User32.WM_GETTEXTLENGTH, 0, null);

I followed your advise to the letter so the parameters ar of the same type as you showed in your tutorial.

Thanks for your nice blog and looking forward to understand this a little more when I receive your answer.
Gravatar

Mark S. Rasmussen wrote on 1/23/2009 12:04 AM

Hi Thorsten,

IntPtr are basically the same type. Both are a numeric 4 byte value, and can thus be converted 1 to 1 without problems. Whether you use int or IntPtr is more of a style issue in my opinion. You should however stick to using just one of the types, and not mix them together as I have lazily done :)
Gravatar

Thorsten Lorenz wrote on 1/23/2009 1:53 AM

Thanks, I understand now.
Do you have any idea, why the Program hands itself at the above mentioned line. It only happens about 5% of the time, usually when I did a lot during the current Windows session and a reboot always fixes the problem.

Post Comment

Name  
Email
Url
Comment
Please add 2 and 6 and type the answer here: