C# exe单例
引言
有时候我们会遇到这种需求,要求winform生成的exe只能够运行一个,不能同时运行多个,也就是我这里所谓的exe单例。winform没有帮我们直接实现exe单例模式,就需要我们通过一些其他的手段来实现单例。
(一)System.Threading.Mutex
Mutex是互斥锁,位于System.Threading命名空间中。顾名思义,它是一个互斥的对象,同一时间只有一个线程可以拥有它。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Test
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//Exe单例
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "testestest", out bool createdNew);
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
MessageBox.Show("程序已经启动");
}
}
}
}
在这里需要定义一个Mutex的变量,使用一个名称来唯一确定自己的ID,我平时选用的是AssemblyInfo.cs里面的Guid,也可以自定义。
评价:简单,精确,基本可以确定唯一。
(二)System.Diagnostics.Process
Process是进程类,通过判断同名进程来判断当前exe是否启动。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
namespace HollyToolManager
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//Exe单例
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "566fb625-d920-44fd-8df9-bd1227005a4d", out bool createdNew);
if (AnotherRuning())
{
MessageBox.Show("程序已经启动");
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
/// <summary>
/// 是否有另一个程序运行
/// </summary>
/// <returns></returns>
private static bool AnotherRuning()
{
Process currentProcess = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);
foreach (Process item in processes)
{
if (item.Id != currentProcess.Id)
{
return true;
}
}
return false;
}
}
}
评价:在一些特殊情况下还是可以重新启动第二个exe的,甚至会出现进程名称重复的问题,即启动的同名进程并不是这个exe。
参考文档
C#中Mutex的用法_执着的涛的博客-CSDN博客_c# mutex
C# Winform 程序EXE单例模式的三种方案详细总结_lightspear的博客-CSDN博客_c# exe单进程
总结
水平有限,目前想到的方法就只有这两个,个人比较推荐使用System.Threading.Mutex,如果各位大佬有更好的解决方案或者我这里说的不对的地方,欢迎留言。