如何确定进程是否已经在使用 c# 运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51148/
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 do I find out if a process is already running using c#?
提问by csjohnst
I have C# winforms application that needs to start an external exe from time to time, but I do not wish to start another process if one is already running, but rather switch to it.
我有一个 C# winforms 应用程序,它需要不时启动一个外部 exe,但如果一个进程已经在运行,我不想启动另一个进程,而是切换到它。
So how in C# would I so this in the example below?
那么在 C# 中我将如何在下面的示例中做到这一点?
using System.Diagnostics;
...
Process foo = new Process();
foo.StartInfo.FileName = @"C:\bar\foo.exe";
foo.StartInfo.Arguments = "Username Password";
bool isRunning = //TODO: Check to see if process foo.exe is already running
if (isRunning)
{
//TODO: Switch to foo.exe process
}
else
{
foo.Start();
}
采纳答案by DaveK
This should do it for ya.
这应该为你做。
//Namespaces we need to use
using System.Diagnostics;
public bool IsProcessOpen(string name)
{
//here we're going to get a list of all running processes on
//the computer
foreach (Process clsProcess in Process.GetProcesses()) {
//now we're going to see if any of the running processes
//match the currently running processes. Be sure to not
//add the .exe to the name you provide, i.e: NOTEPAD,
//not NOTEPAD.EXE or false is always returned even if
//notepad is running.
//Remember, if you have the process running more than once,
//say IE open 4 times the loop thr way it is now will close all 4,
//if you want it to just close the first one it finds
//then add a return; after the Kill
if (clsProcess.ProcessName.Contains(name))
{
//if the process is found to be running then we
//return a true
return true;
}
}
//otherwise we return a false
return false;
}
回答by aku
You can simply enumerate processes using Process.GetProcessesmethod.
您可以使用Process.GetProcesses方法简单地枚举进程。
回答by jmatthias
I think the complete answer to your problem requires understanding of what happens when your application determines that an instance of foo.exe is already running i.e what does '//TODO: Switch to foo.exe process' actually mean?
我认为您的问题的完整答案需要了解当您的应用程序确定 foo.exe 的实例已经在运行时会发生什么,即“//TODO: Switch to foo.exe process”实际上是什么意思?
回答by Gulzar Nazim
I have used the AppActivate function in VB runtime to activate an existing process. You will have to import Microsoft.VisualBasic dll into the C# project.
我在 VB 运行时中使用了 AppActivate 函数来激活现有进程。您必须将 Microsoft.VisualBasic dll 导入 C# 项目。
using System;
using System.Diagnostics;
using Microsoft.VisualBasic;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Process[] proc = Process.GetProcessesByName("notepad");
Interaction.AppActivate(proc[0].MainWindowTitle);
}
}
}
回答by aku
You can use LINQ as well,
您也可以使用 LINQ,
var processExists = Process.GetProcesses().Any(p => p.ProcessName.Contains("<your process name>"));
回答by Mnebuerquo
In a past project I needed to prevent multiple execution of a process, so I added a some code in the init section of that process which creates a named mutex. This mutext was created and acquired before continuing the rest of the process. If the process can create the mutex and acquire it, then it is the first one running. If another process already controls the mutex, then the one which fails is not the first so it exits immediately.
在过去的项目中,我需要防止一个进程的多次执行,所以我在该进程的 init 部分添加了一些代码来创建一个命名的互斥锁。这个互斥体是在继续其余过程之前创建和获取的。如果进程可以创建互斥体并获取它,那么它就是第一个运行的。如果另一个进程已经控制了互斥锁,那么失败的不是第一个,所以它会立即退出。
I was just trying to prevent a second instance from running, due to dependencies on specific hardware interfaces. Depending on what you need with that "switch to" line, you might need a more specific solution such as a process id or handle.
由于对特定硬件接口的依赖,我只是想阻止第二个实例运行。根据您对该“切换到”行的需求,您可能需要更具体的解决方案,例如进程 ID 或句柄。
Also, I had source code access to the process I was trying to start. If you can not modify the code, adding the mutex is obviously not an option.
此外,我可以访问我尝试启动的进程的源代码。如果不能修改代码,添加互斥锁显然不是一种选择。
回答by csjohnst
Mnebuerquo wrote:
Also, I had source code access to the process I was trying to start. If you can not modify the code, adding the mutex is obviously not an option.
Mnebuerquo 写道:
此外,我可以访问我尝试启动的进程的源代码。如果不能修改代码,添加互斥锁显然不是一种选择。
I don't have source code access to the process I want to run.
我没有要运行的进程的源代码访问权限。
I have ended up using the proccess MainWindowHandle to switch to the process once I have found it is alread running:
一旦我发现它已经在运行,我最终使用进程 MainWindowHandle 切换到进程:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
回答by Jay Bazuzi
Two concerns to keep in mind:
需要记住的两个问题:
Your example involved placing a password on a command line. That cleartext representation of a secret could be a security vulnerability.
When enumerating processes, ask yourself which processes you really want to enumerate. All users, or just the current user? What if the current user is logged in twice (two desktops)?
您的示例涉及在命令行上放置密码。秘密的明文表示可能是一个安全漏洞。
在枚举进程时,问问自己你真正想要枚举哪些进程。所有用户,还是只是当前用户?如果当前用户登录两次(两个桌面)怎么办?
回答by Israel Ocbina
I found out that Mutex is not working like in the Console application. So using WMI to query processes that can be seen using Task Manager window will solved your problem.
我发现 Mutex 不像在控制台应用程序中那样工作。因此,使用 WMI 查询使用任务管理器窗口可以看到的进程将解决您的问题。
Use something like this:
使用这样的东西:
static bool isStillRunning() {
string processName = Process.GetCurrentProcess().MainModule.ModuleName;
ManagementObjectSearcher mos = new ManagementObjectSearcher();
mos.Query.QueryString = @"SELECT * FROM Win32_Process WHERE Name = '" + processName + @"'";
if (mos.Get().Count > 1)
{
return true;
}
else
return false;
}
NOTE: Add assembly reference "System.Management" to enable the type intellisense.
注意:添加程序集引用“System.Management”以启用类型智能感知。