Answers:
这是使用名称的一种方法:
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);
}
if/else
长度只有一行的C#语句不需要大括号来表示block语句。这也适用于foreach
和for
声明。归结为编码风格。
for
信息。多年的C#.net开发人员和我从未见过这种风格。就像他们说的那样:“您每天都会学到新东西”。谢谢你的职位和答复..
这是使用反射器后发现的最简单的方法。我为此创建了一个扩展方法:
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
班级是内部的...
同步解决方案:
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的回答很不错;但是,这并不能说明从未开始过该过程的情况。
这是他发布内容的修改版本。
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
我删除了他的ArgumentNullException,因为它实际上是一个空引用异常,并且无论如何它都会被系统抛出,并且我还考虑了这种情况,即该进程从未开始开始,或者使用close()方法关闭了处理。
也许(可能)我错误地读了这个问题,但是您是否在寻找HasExited属性,该属性将告诉您由Process对象代表的进程已经退出(无论是否正常)。
如果您引用的流程具有UI,则可以使用Responding属性来确定UI当前是否正在响应用户输入。
您也可以设置EnableRaisingEvents并处理Exited事件(异步发送),如果要阻止,则调用WaitForExit()。
您可以为所需的流程实例化一次Process实例,并继续使用该.NET Process对象跟踪该流程实例(它将一直跟踪直到您明确对该.NET对象调用Close为止,即使它正在跟踪的流程已终止也是如此) [这是为了让您有时间关闭进程,也称为ExitTime等。]
引用http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:
当关联的进程退出时(也就是说,当操作系统通过正常或异常终止将其关闭时),系统将存储有关该进程的管理信息,并返回到名为WaitForExit的组件。然后,通过使用已退出进程的句柄,Process组件可以访问包括ExitTime的信息。
因为已退出关联的流程,所以组件的Handle属性不再指向现有的流程资源。相反,该句柄只能用于访问有关进程资源的操作系统信息。系统知道流程组件尚未释放的已退出流程的句柄,因此它将ExitTime和Handle信息保留在内存中,直到流程组件专门释放资源为止。因此,每次为流程实例调用“启动”时,在关联的流程终止并且您不再需要有关该流程的任何管理信息时,请调用“关闭”。关闭释放分配给已退出进程的内存。
我尝试了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 );
}
稍后我关闭该应用程序:
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
它有效(到目前为止)
openApplication.HasExited()
,HasExited不是函数。正确的方法是openApplication.HasExited
。
尽管.Net框架支持使用API来按进程ID检查现有进程,但这些功能非常慢。运行Process.GetProcesses()或Process.GetProcessById / Name()会花费大量的CPU周期。
通过ID检查运行进程的更快方法是使用本机API OpenProcess()。如果返回句柄为0,则表明该进程不存在。如果handle不同于0,则说明该进程正在运行。由于获得许可,无法保证此方法在任何时候都可以100%工作。
有许多与此相关的问题,其他似乎已部分解决:
无论其他人提到的属性是否是内部的,如果允许,您仍然可以通过反射从它们获取信息。
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
您可以为快照添加 Win32代码,也可以使用速度较慢的WMI。
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
另一个选择是使用OpenProcess / CloseProcess,但是您仍然会遇到相同的问题,并且抛出的异常与以前相同。
对于WMI-OnNewEvent.Properties [“?”]:
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
您也可以使用计时器每次检查过程
length == 0
应该显示Not Working
),但仍然可以完成工作。