如何在C#中跟踪应用程序的打开实例

时间:2012-05-16 06:09:27

标签: c# semaphore multiple-instances

我想在我的项目中确保安装更新时互相排斥 该项目是多实例的,意味着可以在不关闭其他打开实例的情况下打开实例。有一个名为installUpdates()的函数可以安装可用的更新。由于存在多个实例,因此只有其中一个需要安装更新。我想确保只有一个实例会安装更新 我正在将全局称为noOfInstances(信号量)的变量初始化为0。打开新实例后,变量将增加1.如果有4个打开的实例,那么noOfInstances的值将为4.一旦实例关闭,该值将减少1.用于安装更新我在写: -

if(noOfInstances == 1)
{
   InstallUpdates();
}

现在我的问题是如何以编程方式跟踪我的项目是否打开了一个实例?每个实例可能都有一些我无法识别的唯一ID。我正在使用Windows环境来开发我的c#应用程序。

4 个答案:

答案 0 :(得分:2)

全局Mutex可能是一种更好的机制,可以访问仅精确一次的函数。在这种情况下,我尝试使用短暂超时获取互斥锁。如果你没有获得它 - 别人拥有它。如果成功,请测试是否需要更新,如果是,请安装更新。

优化可能是将测试移到互斥锁之外 - 但是如果在互斥锁范围内需要更新,您仍需要重新测试。

What is a good pattern for using a Global Mutex in C#?

答案 1 :(得分:0)

你可以像这样获得正在运行的进程:

using System.Diagnostics;

int GetInstanceCount(ExeName)
{
    Process[] processlist = Process.GetProcessesByName(ExeName);
    int NoOfInstances = processlist.Count;
    return NoOfInstances;
}

现在像这样实施:

string ExeName = "notepad.exe"//Say Notepad
if(GetInstanceCount(ExeName) == 1)
{
   InstallUpdates();
}

答案 2 :(得分:0)

您可以使用Process.GetProcesses按名称获取流程

var processes = Process.GetProcesses Method (ProcessName)
if (processes!= null)
{
  int runningInstances = processes.Length;
}

答案 3 :(得分:0)

虽然我过去实现了@ stephbu的互斥模式,但最近的要求是如果程序启动两次,应该将运行的实例放到前面。

为此,我尝试连接到命名管道。如果我无法连接,这是第一个实例,我创建命名管道然后正常做事。如果我可以连接,这是第二个实例,我通过管道发送命令并退出。

在命名管道上接收命令我可以做任何我想做的事情,比如将主窗口置于顶部。

但是,如果您真的想要对管道执行某些操作,则此解决方案才有意义。如果您只想阻止应用程序运行两次,@ stephbu的互斥锁答案是可行的方法。