如何知道某个进程是否正在运行?
这是一种名为做到这一点:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
你也可以遍历所有的过程,获得后面操纵ID:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
Process.GetProcesses()
是要走的路。但是,您可能需要使用一个或多个不同的标准来查找您的流程,具体取决于它的运行方式(即作为服务或普通应用程序,不管它是否具有标题栏)。
如果您将此方法放在一个循环中,则会花费大量的CPU周期。我建议使用GetProcessByName()或GetProcessByID()。 – 2016-07-08 16:55:34
这取决于你想要这个功能的可靠程度。如果您想知道您拥有的特定流程实例是否仍在运行并且100%准确可用,那么您的运气不好。原因在于,从被管理的过程对象中,只有两种方法可以识别过程。
第一个是进程ID。不幸的是,进程id不是唯一的,可以回收。在进程列表中搜索匹配的Id只会告诉你有一个进程使用相同的ID运行,但它不一定是你的进程。
第二项是过程句柄。它与Id一样存在相同的问题,并且与其合作更加尴尬。
如果您正在寻找中等级别的可靠性,那么检查当前进程列表以找到具有相同ID的进程就足够了。
也许(可能)我错误地阅读了这个问题,但是您是否在寻找HasExited属性,它会告诉您Process对象所代表的进程已经退出(通常与否)。
如果你的程序中有一个参考,以具有UI可以使用响应属性来确定UI目前正对用户输入或没有。
您还可以设置EnableRaisingEvents并处理Exited事件(它是异步发送的),或者如果您想阻塞,请调用WaitForExit()。
同步溶液:
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
异步溶液:
void RegisterProcessExit(Process process)
{
// NOTE there will be a race condition with the caller here
// how to fix it is left as an exercise
process.Exited += process_Exited;
}
static void process_Exited(object sender, EventArgs e)
{
Console.WriteLine("Process has exited.");
}
对于第一个选项:我怎么知道这个过程是否是从第一个地方开始的? – reshefm 2008-11-06 11:39:31
这是我使用反射后发现的最简单的方法。 我创建该扩展方法:
public static class ProcessExtensions
{
public static bool IsRunning(this Process process)
{
if (process == null)
throw new ArgumentNullException("process");
try
{
Process.GetProcessById(process.Id);
}
catch (ArgumentException)
{
return false;
}
return true;
}
}
的Process.GetProcessById(processId)
方法调用ProcessManager.IsProcessRunning(processId)
方法和在情况下的处理不存在引发ArgumentException
。由于某种原因,ProcessManager
类是内部的...
这是一个非常好的答案;但是,您不应该通过参数null异常(因为无论如何都会抛出null引用异常,并且您没有对异常执行任何操作。而且,如果您没有调用Start(),则会得到InvalidOperationException,或者你调用了close()方法,我发布了另一个应答来解决这两种情况 – Aelphaeis 2014-01-31 14:52:48
您可以为您想要的进程实例化一次Process实例,并使用该.NET进程对象跟踪进程(它会一直跟踪,直到您调用Close该.NET对象显式地,即使它正在跟踪的进程已经死了[这是为了能够给你关闭进程的时间,也就是ExitTime等。])
引用http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:
当相关联的处理退出(即,当通过正常或异常终止关闭由 操作系统),该系统对 存储管理信息处理并返回到已调用WaitForExit的组件 。过程组件然后可以通过使用 句柄来访问包含ExitTime的信息, Handle到退出的进程。
由于关联进程已退出,因此 组件的Handle属性不再指向现有的进程资源。相反, 句柄只能用于访问有关进程资源的操作系统的 信息。系统知道处理 已退出进程组件, 尚未释放的进程,因此它会将ExitTime和Handle信息保留在内存中,直到 进程组件专门释放资源为止。由于这个原因,当您调用Process实例的任何时候,您都可以拨打 ,当 关联进程已终止,并且不再需要关于它的任何 管理信息时,请调用Close。关闭将分配给内存 的内存释放到退出的进程。
我试图Coincoin的解决方案:
处理一些文件之前,我复制它作为一个临时文件并打开它。
当我完成后,我关闭应用程序,如果它仍处于打开状态,并删除 临时文件:
我只是用一个过程变量和事后检查:
private Process openApplication;
private void btnOpenFile_Click(object sender, EventArgs e) {
...
// copy current file to fileCache
...
// open fileCache with proper application
openApplication = System.Diagnostics.Process.Start(fileCache);
}
后来我关闭应用程序:
...
openApplication.Refresh();
// close application if it is still open
if (!openApplication.HasExited()) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete(fileCache);
它的工作原理(到目前为止)
string process="notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
人所以你可以使用一个定时器来检查每个进程
reshefm有一个相当不错的答案;然而,这并没有说明这个过程从未开始的情况。
这是他发布的内容的修改版本。
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
我脱下ArgumentNullException,因为它实际上是想要一个空引用异常,它就会被系统反正扔,我也占了其中的过程是从来没有开始,开始的形势或接近( )方法被用来关闭该过程。
这应该是一个班轮:
public static class ProcessHelpers {
public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0;
}
尽管通过有关进程ID检查现有流程的.Net框架支持的API,这些功能都非常慢。运行Process.GetProcesses()或Process.GetProcessById/Name()会花费大量的CPU周期。
通过ID检查正在运行的进程的更快速的方法是使用本地API OpenProcess()。如果返回句柄为0,则该过程不存在。如果句柄不是0,则进程正在运行。无法保证此方法在许可的情况下始终可以100%正常工作。
这正是我一直在寻找的。即使这是一个非常古老的帖子,你会向我解释这是如何有效的C#。我不怀疑它,我认为它有效,但我从来没有见过没有{}。 – MatthewD 2015-11-18 19:06:12
@MatthewD:C#`只有一行的if/else`语句不需要用花括号来表示块语句。这也适用于“foreach”和“for”语句。它归结为编码风格。 – Hallmanac 2015-11-24 01:36:28
我也对此进行了一些研究,发现信息,但我没有看到“for”信息。多年的c#.net开发者和我从未见过这种风格。就像他们说的,“你每天都会学到新的东西”。谢谢你的帖子和回复.. – MatthewD 2015-11-25 03:06:47