C# 如何知道进程是否正在运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/262280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I know if a process is running?
提问by reshefm
When I get a reference to a System.Diagnostics.Process
, how can I know if a process is currently running?
当我获得对 a 的引用时,我System.Diagnostics.Process
如何知道进程当前是否正在运行?
采纳答案by Patrick Desjardins
This is a way to do it with the name:
这是一种使用名称的方法:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
You can loop all process to get the ID for later manipulation:
您可以循环所有进程以获取 ID 以供以后操作:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
回答by Jeff Kotula
Process.GetProcesses()
is the way to go. But you may need to use one or more different criteria to find your process, depending on how it is running (i.e. as a service or a normal app, whether or not it has a titlebar).
Process.GetProcesses()
是要走的路。但是您可能需要使用一个或多个不同的标准来查找您的进程,这取决于它的运行方式(即作为服务还是作为普通应用程序,无论它是否具有标题栏)。
回答by JaredPar
It depends on how reliable you want this function to be. If you want to know if the particular process instance you have is still running and available with 100% accuracy then you are out of luck. The reason being that from the managed process object there are only 2 ways to identify the process.
这取决于您希望此功能有多可靠。如果您想知道您拥有的特定流程实例是否仍在运行并以 100% 的准确率可用,那么您就不走运了。原因是从托管进程对象只有两种方法可以识别进程。
The first is the Process Id. Unfortunately, process ids are not unique and can be recycled. Searching the process list for a matching Id will only tell you that there is a process with the same id running, but it's not necessarily your process.
第一个是进程 ID。不幸的是,进程 ID 不是唯一的,可以回收。在进程列表中搜索匹配的 Id 只会告诉您有一个具有相同 ID 的进程正在运行,但它不一定是您的进程。
The second item is the Process Handle. It has the same problem though as the Id and it's more awkward to work with.
第二项是进程句柄。尽管它与 Id 存在相同的问题,但使用起来更尴尬。
If you're looking for medium level reliability then checking the current process list for a process of the same ID is sufficient.
如果您正在寻找中等级别的可靠性,那么检查具有相同 ID 的进程的当前进程列表就足够了。
回答by JaredPar
Maybe (probably) I am reading the question wrongly, but are you looking for the HasExited property that will tell you that the process represented by your Process object has exited (either normally or not).
也许(可能)我读错了这个问题,但是您是否正在寻找 HasExited 属性,该属性会告诉您 Process 对象表示的进程已退出(正常与否)。
If the process you have a reference to has a UI you can use the Responding property to determine if the UI is currently responding to user input or not.
如果您引用的进程有一个 UI,您可以使用 Responding 属性来确定 UI 当前是否正在响应用户输入。
You can also set EnableRaisingEvents and handle the Exited event (which is sent asychronously) or call WaitForExit() if you want to block.
您还可以设置 EnableRaisingEvents 并处理 Exited 事件(异步发送)或如果您想阻止则调用 WaitForExit()。
回答by Coincoin
Synchronous solution :
同步解决方案:
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
Asynchronous solution:
异步解决方案:
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.");
}
回答by reshefm
This is the simplest way I found after using reflector. I created an extension method for that:
这是我在使用反射器后发现的最简单的方法。我为此创建了一个扩展方法:
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;
}
}
The Process.GetProcessById(processId)
method calls the ProcessManager.IsProcessRunning(processId)
method and throws ArgumentException
in case the process does not exist. For some reason the ProcessManager
class is internal...
该Process.GetProcessById(processId)
方法调用该ProcessManager.IsProcessRunning(processId)
方法并ArgumentException
在进程不存在的情况下抛出。出于某种原因,ProcessManager
该类是内部的...
回答by George Birbilis
You can instantiate a Process instance once for the process you want and keep on tracking the process using that .NET Process object (it will keep on tracking till you call Close on that .NET object explicitly, even if the process it was tracking has died [this is to be able to give you time of process close, aka ExitTime etc.])
您可以为您想要的进程实例化一个 Process 实例,并使用该 .NET Process 对象继续跟踪该进程(它将继续跟踪,直到您显式调用该 .NET 对象上的 Close,即使它正在跟踪的进程已经死亡[这是为了能够给你进程关闭的时间,又名 ExitTime 等])
Quoting http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:
引用http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:
When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit. The Process component can then access the information, which includes the ExitTime, by using the Handle to the exited process.
Because the associated process has exited, the Handle property of the component no longer points to an existing process resource. Instead, the handle can be used only to access the operating system's information about the process resource. The system is aware of handles to exited processes that have not been released by Process components, so it keeps the ExitTime and Handle information in memory until the Process component specifically frees the resources. For this reason, any time you call Start for a Process instance, call Close when the associated process has terminated and you no longer need any administrative information about it. Close frees the memory allocated to the exited process.
当关联的进程退出时(即当操作系统通过正常或异常终止将其关闭时),系统存储有关进程的管理信息并返回到调用 WaitForExit 的组件。然后,Process 组件可以通过使用已退出进程的句柄来访问包括 ExitTime 在内的信息。
由于关联进程已退出,组件的 Handle 属性不再指向现有进程资源。相反,句柄只能用于访问操作系统关于进程资源的信息。系统知道 Process 组件尚未释放的已退出进程的句柄,因此它会将 ExitTime 和 Handle 信息保留在内存中,直到 Process 组件专门释放资源。因此,任何时候为 Process 实例调用 Start 时,在关联进程终止并且不再需要有关它的任何管理信息时调用 Close。Close 释放分配给退出进程的内存。
回答by Hyman Griffin
I tried Coincoin's solution :
Before processing some file, I copy it as a temporary file and open it.
When I'm done, I close the application if it is still open and delete
the temporary file :
I just use a Process variable and check it afterwards :
我尝试了 Coincoin 的解决方案:
在处理某个文件之前,我将其复制为临时文件并打开它。
完成后,如果应用程序仍处于打开状态,我将关闭该应用程序并删除临时文件:
我只使用一个 Process 变量,然后再检查它:
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 );
}
Later I close the application :
后来我关闭了应用程序:
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
It works ( so far )
它有效(到目前为止)
回答by berkay
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
also you can use a timer for checking the process every time
您也可以使用计时器每次检查过程
回答by Aelphaeis
reshefm had a pretty nice answer; however, it does not account for a situation in which the process was never started to begin with.
reshefm 有一个很好的答案;然而,它没有考虑到进程从未开始的情况。
Here is a a modified version of what he posted.
这是他发布的内容的修改版本。
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
I removed his ArgumentNullException because its actually suppose to be a null reference exception and it gets thrown by the system anyway and I also accounted for the situation in which the process was never started to begin with or the close() method was used to close the process.
我删除了他的 ArgumentNullException 因为它实际上被认为是一个空引用异常,无论如何它都会被系统抛出,我还考虑了进程从未开始或使用 close() 方法关闭的情况过程。