如何阻止给 一个程序 开启多个实例 ?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何阻止给 一个程序 开启多个实例 ?相关的知识,希望对你有一定的参考价值。
咨询区
C. Dragon 76:
在 .NET 中是否有比较好的方法可以阻止一个 application 被同时开启了多个实例?如果没有好的办法,那么只能退其次,给每个 application 配一些操作规范。
回答区
ImJustPondering:
我总结有两种解法。
使用 Meutx。
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global\\\\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
关于 Mutex
更多资料,可参考:http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx
使用 Process
可以迭代进程列表,判断是否已经存在该进程名即可,参考如下代码:
using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
int procCount = 0;
foreach (Process pp in Process.GetProcesses())
{
try
{
if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
{
procCount++;
if(procCount > 1) {
Application.Exit();
return;
}
}
}
catch { }
}
Application.Run(new Form1());
}
Tono Nam:
其实可以仿 linux 上生成进程文件的方式,所以要做的就是在程序启动后,在某一个文件中写入一个默认的 uniqueid 值,参考如下代码:
public static void PreventMultipleInstance(string applicationId)
{
// Under Windows this is:
// C:\\Users\\SomeUser\\AppData\\Local\\Temp\\
// Linux this is:
// /tmp/
var temporaryDirectory = Path.GetTempPath();
// Application ID (Make sure this guid is different accross your different applications!
var applicationGuid = applicationId + ".process-lock";
// file that will serve as our lock
var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
try
{
// Prevents other processes from reading from or writing to this file
var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_InstanceLock.Lock(0, 0);
MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
// todo investigate why we need a reference to file stream. Without this GC releases the lock!
System.Timers.Timer t = new System.Timers.Timer()
{
Interval = 500000,
Enabled = true,
};
t.Elapsed += (a, b) =>
{
try
{
_InstanceLock.Lock(0, 0);
}
catch
{
MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
}
};
t.Start();
}
catch
{
// Terminate application because another instance with this ID is running
Environment.Exit(102534);
}
}
点评区
这个需求本质上和防重复登录时一样的,大概三种吧:
机器内作用域:
Metux,Process 是一个好办法。
跨机器或局域网作用域:
生成 PID 文件是一个好办法。
局域网,广域网:
可用 redis,zookeeper 之类的全局锁机制。
以上是关于如何阻止给 一个程序 开启多个实例 ?的主要内容,如果未能解决你的问题,请参考以下文章