3
好吧,我花了一点时间在这个网站上弄清楚如何启动一个“子进程”进程(即新进程为我设置了窗口父项)使用来自C#的Win32调用。只要它不跨越UAC边界,它就可以工作。精细。启动Win32进程A启动进程B - 获取B的ID/HWND
现在我试图用一个卸载程序(进程A)来引导临时程序(进程B),它实际上完成了这项工作。进程A在创建B后会消失。我的代码需要一个进程ID,从该进程ID获取传递给SetParent的窗口句柄。看起来像这样:
Process p = new Process();
try
{
p.EnableRaisingEvents = true;
p.StartInfo.FileName = fileName;
p.StartInfo.Arguments = arguments;
if (p.Start())
{
p.WaitForInputIdle(10000);
IntPtr pHwnd = p.MainWindowHandle;
if (pHwnd == IntPtr.Zero)
{
return null;
}
IntPtr currentHwnd = Process.GetCurrentProcess().MainWindowHandle;
if (SetParent(pHwnd, currentHwnd) == 0)
{
if (Marshal.GetLastWin32Error() == 5) // access denied
{
// Need to launch privileged process that launches process
// and sets parent on UAC enabled OS.
}
else
{
return null;
}
}
// AND SO ON AND SO FORTH
只要p不会消失,就可以很好地工作。在这种情况下,p在开始p'后会出现繁荣。无论如何,P从来没有窗口句柄。
那么,我该如何监测p,看看它是否开始p'并获得p'的id(或更重要的是窗口句柄)?我可以从ID获得HWND,但是我需要获得一个或另一个。
谢谢!
感谢您的回答。奇怪的是,WaitForInputIdle很快返回并且p(proc)不为null。所以p.MainWindowHandle没有NullPointerException。它只是返回IntPtr.Zero。所以我现在返回null。我需要的是一种监控p进程调用的方法,并检查它是窗口句柄的新进程(假设p没有)。 – paul 2011-06-01 16:34:55
请注意,在查看您的代码时,我非常确定在调用Start()之后,proc永远不会为空。我不认为启动方法会处理过程对象实例。相反,如果失败并且/或者设置了HasExited和ExitCode道具,它会抛出异常。 – paul 2011-06-01 16:41:33
可以尝试使用SendMessageTimeout并查看窗口是否响应消息。如果它没有回应,你可以假设它已经死了。 [查看此链接了解有关SendMessageTimeout的详细信息](http://msdn.microsoft.com/zh-cn/library/ms644952(v = vs.85).aspx)我认为任何解决方案都将涉及使用更多WIN API调用以某种方式。 – 2011-06-01 17:38:34