我如何确定某个进程是否已经在使用c#运行?
时间:2020-03-05 18:49:48 来源:igfitidea点击:
我有Cwinforms应用程序,需要不时启动一个外部exe,但是我不希望启动另一个进程(如果已经在运行),而是切换到该进程。
那么在下面的示例中我该怎么做呢?
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(); }
解决方案
回答
这应该为我们做。
检查流程
//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; }
回答
我们可以简单地使用Process.GetProcesses方法枚举进程。
回答
我认为要完全解决问题,需要了解应用程序确定foo.exe实例已在运行时发生的情况,即" // TODO:切换到foo.exe进程"的实际含义是什么?
回答
我已经在VB运行时中使用AppActivate函数来激活现有进程。
我们将必须将Microsoft.VisualBasic dll导入Cproject。
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); } } }
回答
我们也可以使用LINQ,
var processExists = Process.GetProcesses().Any(p => p.ProcessName.Contains("<your process name>"));
回答
在过去的项目中,我需要防止一个进程的多次执行,因此我在该进程的init部分中添加了一些代码,以创建一个命名的互斥体。在继续其余过程之前,已创建并获取了此文本。如果该进程可以创建并获取互斥锁,则它是第一个运行的互斥锁。如果另一个进程已经控制了互斥锁,那么失败的不是第一个,因此它会立即退出。
由于对特定硬件接口的依赖性,我只是试图阻止第二个实例运行。根据"切换到"行的需要,我们可能需要更具体的解决方案,例如进程ID或者句柄。
另外,我可以访问试图启动的过程的源代码。如果我们无法修改代码,则添加互斥锁显然不是一种选择。
回答
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.
我没有源代码可以访问要运行的进程。
一旦发现进程已在运行,我就结束了使用过程MainWindowHandle切换到该进程:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);
回答
请记住两个注意事项:
- 示例涉及在命令行上放置密码。明文表示的机密可能是安全漏洞。
- 枚举过程时,请问问自己我们真正要枚举的过程。所有用户,还是仅当前用户?如果当前用户登录两次(两个台式机)怎么办?