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