2013-04-30 56 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. 
    } 
}