2011-06-01 56 views
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,但是我需要获得一个或另一个。

谢谢!

回答

0

一个简单的解决方案可能是,在试图获取其MainWindowHandle之前检查p是否为空。这里有一些示例代码,如果需要,您可以进行调整。

  using (Process proc = new Process()) 
      { 

       proc.StartInfo.FileName = filename; 
       proc.StartInfo.UseShellExecute = false; 
       proc.StartInfo.WorkingDirectory = ClientInstallPath; 
       proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

       proc.Start(); 

       if (proc != null) 
       { 
        proc.WaitForExit(); 
        returnCode = proc.ExitCode; 
       } 
      } 
+0

感谢您的回答。奇怪的是,WaitForInputIdle很快返回并且p(proc)不为null。所以p.MainWindowHandle没有NullPointerException。它只是返回IntPtr.Zero。所以我现在返回null。我需要的是一种监控p进程调用的方法,并检查它是窗口句柄的新进程(假设p没有)。 – paul 2011-06-01 16:34:55

+0

请注意,在查看您的代码时,我非常确定在调用Start()之后,proc永远不会为空。我不认为启动方法会处理过程对象实例。相反,如果失败并且/或者设置了HasExited和ExitCode道具,它会抛出异常。 – paul 2011-06-01 16:41:33

+0

可以尝试使用SendMessageTimeout并查看窗口是否响应消息。如果它没有回应,你可以假设它已经死了。 [查看此链接了解有关SendMessageTimeout的详细信息](http://msdn.microsoft.com/zh-cn/library/ms644952(v = vs.85).aspx)我认为任何解决方案都将涉及使用更多WIN API调用以某种方式。 – 2011-06-01 17:38:34