2013-04-30 143 views
4

我有這個循環作爲進程連續運行,以檢查mstsc.exe是否正在運行。強制關閉進程

for (; ;) 
{ 
    System.Diagnostics.Process[] pname = System.Diagnostics.Process.GetProcessesByName("mstsc"); 

    if (pname.Length != 0) 
    { 

    } 
    else 
    { 
     System.Diagnostics.Process.Start(@"mstsc.exe"); 
    } 
    System.Threading.Thread.Sleep(3000); 
} 

問題是,在註銷,重新引導或關機時我得到了這個。

enter image description here

我試圖結束對Form_Closing或

Microsoft.Win32.SystemEvents.SessionEnded += 
    new Microsoft.Win32.SessionEndedEventHandler(SystemEvents_SessionEnded); 

,我仍然得到這個過程...

我怎麼可能迫使這個過程中正確地殺人?

+0

一些嘗試是將一個布爾值,你可以從該環外改變。當你觸發表單時,將其更改爲false。 – Nomad101 2013-04-30 17:08:50

+10

'我怎麼能強制這個過程正確地殺死。「...... Cyber​​dyne Systems在創建SkyNet時提出了完全相同的問題。 – 2013-04-30 17:10:17

+0

這是我的理解,Thread.Sleep將不允許任何消息在當前線程處理'睡覺'時處理。您可能也對這篇文章感興趣:http://www.albahari.com/threading/ – 2013-04-30 17:12:51

回答

0

Timer,而不是在循環System.Threading.Thread.Sleep

timer.Tick += new EventHandler(timer_Tick); 
timer.Interval = (1000) * (2);    
timer.Enabled = true;      
timer.Start(); 

void timer_Tick(object sender, EventArgs e) 
    { 
     System.Diagnostics.Process[] pname = System.Diagnostics.Process.GetProcessesByName("mstsc"); 

     if (pname.Length != 0) 
     { 

     } 
     else 
     { 
     System.Diagnostics.Process.Start(@"mstsc.exe"); 
     } 
    } 
+0

這樣做...謝謝大家 – 2013-04-30 18:26:55

1

您可以使用Thread.Sleep將循環移動到單獨的後臺線程。這樣,當你的程序退出時,它將被無聲地殺死。

+0

這就是它。 ..一個獨立的過程只爲循環,嘗試關閉它的過程或另一個,它只是不會死的正確。 – 2013-04-30 17:30:46

+0

你不需要創建一個單獨的進程,創建一個線程。 'var t = new Thread(your_method_with_loop); t.IsBackground = TRUE; t.Start();' – alex 2013-04-30 18:47:45

0

1)你可以有System.Diagnostic.Process raise an event當處理退出使用循環,而不是:

2)您是否嘗試過使用Thread.Join代替了Thread.Sleep?這將導致消息繼續抽水;所以即使在睡眠中,如果您收到SystemEvent,它也能夠被處理。

3)你有什麼樣的應用程序?它是一個控制檯應用程序或Windows窗體/ WPF應用程序?你有沒有什麼可以將Windows消息(Dispatcher,等等)放置到位?

3

當進程有子進程時會發生這種情況。你必須殺死整個進程樹。從鏈接

Kill process tree programmatically in C#

以上代碼(由Gravitas提供):

/// <summary> 
/// Kill a process, and all of its children. 
/// </summary> 
/// <param name="pid">Process ID.</param> 
private static void KillProcessAndChildren(int pid) 
{ 
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid); 
    ManagementObjectCollection moc = searcher.Get(); 
    foreach (ManagementObject mo in moc) 
    { 
     KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); 
    } 
    try 
    { 
     Process proc = Process.GetProcessById(pid); 
     proc.Kill(); 
    } 
    catch (ArgumentException) 
    { 
     // Process already exited. 
    } 
}