When launching a process through winapi calls (CreateProcessAsUserW
for instance), you get a process and thread handle. With this you could get the PID of the process and with that you could do a Process.GetProcessById
call. However, when the process has already terminated in the meantime this call will fail.
Is there a way to get a Process
object by handle instead?
I'm now using GetExitCodeProcess
to at least get some info, but I would rather return a Process
object with the relevant properties set.
CodePudding user response:
I "solved" the problem by doing the following:
// Construct Process object through private constructor, taking the PID. This also works when the process has already exited.
Process new_process = Activator.CreateInstance(typeof(Process), BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { ".", false, (int)pid, null }, null, null) as Process;
// Wrap the handle and give ownership to wrapper
SafeProcessHandle safe_handle = new SafeProcessHandle((IntPtr)process_handle, true);
// Set interal process handle for Process object through private method. This prevents the .ExitCode accessor to throw an exception.
typeof(Process).GetMethod("SetProcessHandle", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(new_process, new object[] { safe_handle });
This works, but is kinda not great. Because it accesses two private functions through reflection. For more info about the internals of the Process object please have a look here.