如何使用c#查明进程是否已在运行?

时间:2008-09-09 02:54:07

标签: c# winforms external-process

我有C#winforms应用程序,需要不时启动外部exe,但我不希望启动另一个进程,如果一个已经在运行,而是切换到它。

那么在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(); 
}

9 个答案:

答案 0 :(得分:31)

这应该为你做。

Check Processes

//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;
}


答案 1 :(得分:22)

你也可以使用LINQ,

var processExists = Process.GetProcesses().Any(p => p.ProcessName.Contains("<your process name>"));

答案 2 :(得分:6)

我在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);
        }
    }
}

答案 3 :(得分:4)

您可以使用Process.GetProcesses方法简单地枚举流程。

答案 4 :(得分:2)

我发现Mutex不像在Console应用程序中那样工作。因此,使用WMI查询可以使用“任务管理器”窗口查看的进程将解决您的问题。

使用类似的东西:

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;
}

注意:添加程序集引用“System.Management”以启用intellisense类型。

答案 5 :(得分:1)

我认为对您的问题的完整答案需要了解当您的应用程序确定foo.exe的实例已在运行时会发生什么,即'// TODO:切换到foo.exe进程'究竟是什么意思?

答案 6 :(得分:1)

在过去的项目中,我需要阻止多个进程的执行,所以我在该进程的init部分添加了一些代码,用于创建一个命名的互斥锁。在继续该过程的其余部分之前,创建并获取此mutext。如果进程可以创建互斥锁并获取它,则它是第一个运行的。如果另一个进程已经控制了互斥锁,则失败的进程不是第一个进程,因此它会立即退出。

由于依赖于特定的硬件接口,我只是试图阻止第二个实例运行。根据“切换到”行所需的内容,您可能需要更具体的解决方案,例如流程ID或句柄。

此外,我有源代码访问我试图启动的过程。如果您无法修改代码,那么添加互斥锁显然不是一种选择。

答案 7 :(得分:1)

要牢记两个问题:

  1. 你的例子涉及放置一个 命令行上的密码。那 明文代表一个秘密 可能是一个安全漏洞。

  2. 在枚举流程时,请询问 你自己真正处理你自己 想要列举。所有用户,或 只是当前的用户?怎么样的呢? 当前用户登录两次(两次 桌面)?

答案 8 :(得分:0)

  

Mnebuerquo写道:

     
    

另外,我有源代码访问权限     过程我试图开始。如果你     无法修改代码,添加     mutex显然不是一种选择。

  

我没有源代码访问我想要运行的进程。

我最终使用proccess MainWindowHandle切换到进程,一旦我发现它已经运行:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 public static extern bool SetForegroundWindow(IntPtr hWnd);
相关问题