2012-02-21 54 views
3

另一个问题在这里。 我只想知道是否可以使用C#结束任务这些应用程序。C#结束任务没有结束进程

喜欢:有4个记事本应用程序已打开。我只想关闭第二个记事本应用程序。但是当我尝试使用process.Kill时,所有4个记事本都被关闭了。有什么办法只关闭指定的注释?

这里是我的示例代码:

foreach (Process p in Process.GetProcesses(".")) 
{ 
    if (p.MainWindowTitle.Length > 0) 
    { 
     if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt") 
     { 
      p.Kill(); 
     } 
    } 
} 
+2

那么你通过所有的过程和杀戮循环所有有记事本名称的文本...更改你的算法以杀死第二个,并在完成时离开循环 – MBen 2012-02-21 08:08:15

+0

也许所有的记事本应用程序都有相同的标题?如果可能的话,通过它的ID来终止一个进程总是一个好方法 – Beatles1692 2012-02-21 08:09:45

+0

它只是不断让我惊讶,有多少C#程序员试图自动化记事本。只需在窗体上放置一个编辑控件即可。繁荣,你可以即时控制你自己的记事本。 – 2012-02-21 08:11:34

回答

3

您需要使用过程的开始时间来寻找第二次运行记事本。

Process[] processes = (from prc in Process.GetProcessesByName("notepad") 
         orderby prc.StartTime 
         select prc).ToArray(); 

if (processes.Count() > 1) 
    processes[1].Kill(); 
+4

不能依赖PIDs分配机制。基本上,你应该知道的关于PID的唯一方法是它不会随着时间而改变,并且在任何给定的时间点都是唯一的。 – penartur 2012-02-21 08:12:07

+0

我并不是要依靠特定的进程ID,而是依赖于它们创建的顺序。我已经改写了我的答案。 – 2012-02-21 08:33:17

+0

如果您没有使用PID来识别您想要杀死的进程,则不应该真的这样做,因为您可能以非预期的方式杀死其他进程。为什么你需要关闭第二个记事本,而不是像你在其他4例子? – Robert 2012-02-21 08:39:23

0

您在整个过程中foreach (Process p in Process.GetProcesses("."))迭代循环并杀死任何进程与开始"NotepadName.txt"标题。

如果你只想杀死第二个实例,你将不得不修改循环中的逻辑以更具选择性。

int i = 0; 
foreach (Process p in Process.GetProcesses(".")) 
{ 
    if (p.MainWindowTitle.Length > 0) 
    { 
     if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt") 
     { 
      i++; 
      if(i == 2){ 
       p.Kill(); 
       break; 
      } 
     } 
    } 
} 
+0

为了杀死第二个实例,我们应该定义“second”是什么意思,或者他们用什么顺序来为进程编号。你的代码基本上会杀死_some_记事本进程(如果有多个记事本进程)。不_second_,但_some_。 – penartur 2012-02-21 08:46:02

+0

我知道这段代码的缺点。这是对OP原始代码的修正。 OP简单地陈述“我只想关闭第二个记事本应用程序”。并没有指定“第二个”是什么意思。如果你有更多的信息,请发表一个答案。 – 2012-02-21 09:25:18

+0

我已经问过OP,它们是什么意思,“第二”,但我敢肯定它们并不意味着“一些”。而且你的代码可能会让人困惑,因为在试图杀死_some_进程时,它会用'i'做一些事情,根本不需要,就好像在Process.GetProcesses中的特定索引处选择值是有道理的。 – penartur 2012-02-21 09:31:19

0

首先,我想你的意思是你只想关闭正在查看NotepadName.txt文件的记事本进程。您可能试图拒绝对该文件的访问(或者出于任何原因关闭访问该文件的人)。所以我忽略了“第二”部分。

我运行了你的代码并进行了测试,并且只能关闭正在访问我定位的文件的记事本进程。

但是我注意到你的比较是绝对不正确的。

//not all processes have a string of 31 characters 
//so sometimes it will trigger an exception 
if (p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt") 
    { 
     p.Kill(); 
    } 

你的目的,更换

if (p.MainWindowTitle.Contains("NotepadName.txt")) 
    { 
     p.Kill(); 
    } 

从我跑的测试,这应该工作。

+0

我的错。它应该只有: if(p.MainWindowTitle.ToString ==“”) { p.Kill(); } //谢谢btw。 – 2012-02-21 23:32:34

+0

如果你有工作,记得把问题标记为已回答 – 2012-02-22 07:59:16

0

有很多搞乱PIDs,所以我必须写一个更清晰的答案,每个人都回答的问题(虽然这可能不是一个原始问题)。

因此,为了杀第二(在过程开始时的顺序)工艺fullfilling在你的榜样的条件,你应该写

var processToKill = (from p in Process.GetProcesses(".") where p.MainWindowTitle.Length > 0 and p.MainWindowTitle.Substring(0, 31) == "NotepadName.txt" order by p.StartTime).Skip(1).FirstOrDefault(); 
if(processToKill != null) 
{ 
    processToKill.Kill(); 
}