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

本文关键字:实例 应用程序 跟踪 | 更新日期: 2023-09-27 18:34:30

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

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

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

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

全局互斥可能是将访问限制为仅一次函数的更好机制。 在这种情况下,我会尝试在短时间内获取互斥锁。 如果你未能获得它 - 其他人拥有它。 如果成功,请测试是否需要更新,如果需要,请安装更新。

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

在 C# 中使用全局互斥体的良好模式是什么?

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

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

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

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

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

但是,仅当您确实想如上所述对管道执行某些操作时,此解决方案才有意义。如果您只想阻止应用程序运行两次,@stephbu的互斥答案就是要走的路。

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

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