[英]How to restrict a program to a single instance
我有一个 C# 控制台应用程序,我想限制我的应用程序一次只运行一个实例。 我如何在 C# 中实现这一点?
我会使用互斥锁
static void Main()
{
string mutex_id = "MY_APP";
using (Mutex mutex = new Mutex(false, mutex_id))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance Already Running!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
// Do stuff
}
}
如果您决定为此目的使用互斥锁,则您应该注意一些陷阱:
如果您想将应用程序限制为每台机器一个实例(即不是每个登录用户一个实例),那么您需要互斥锁名称以前缀Global\\
开头。 如果不添加此前缀,操作系统将为每个用户创建互斥锁的不同实例。
如果您在启用了 UAC 的 Windows Vista 或更高版本的计算机上运行,并且由于某种机会当前应用程序实例以管理员身份运行,则下一个实例将无法检测到它,并且您将获得权限异常。 为避免这种情况,您需要在创建互斥锁时为其指定一组不同的权限。
方法很多,比如——
每个演示如下:
http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
http://www.codeproject.com/KB/cs/restricting_instances.aspx
http://www.codeproject.com/KB/cs/singleinstance.aspx
每个都有其优点和缺点。 但我相信创建互斥锁是最好的选择。
添加此答案是因为以前的答案在 .net core1.1 的 linux(已测试 ubuntu 14.0.4)上不起作用,并且因为此问题在搜索结果中排名靠前。 @MusuNaji 的解决方案的变化,如果它对你来说还不是很明显。
private static bool AlreadyRunning()
{
Process[] processes = Process.GetProcesses();
Process currentProc = Process.GetCurrentProcess();
logger.LogDebug("Current proccess: {0}", currentProc.ProcessName);
foreach (Process process in processes)
{
if (currentProc.ProcessName == process.ProcessName && currentProc.Id != process.Id)
{
logger.LogInformation("Another instance of this process is already running: {pid}", process.Id);
return true;
}
}
return false;
}
这个答案也发布在我的 dotnet core 特定问题上: Linux 上的单实例 dotnetcore cli 应用程序
这是一个对我有用的解决方案
private static bool AlreadyRunning()
{
Process[] processes = Process.GetProcesses();
Process currentProc = Process.GetCurrentProcess();
foreach (Process process in processes)
{
try
{
if (process.Modules[0].FileName == System.Reflection.Assembly.GetExecutingAssembly().Location
&& currentProc.Id != process.Id)
return true;
}
catch (Exception)
{
}
}
return false;
}
然后我在程序启动时检查这个方法的输出。
对我来说最直接的答案,如下所示,取自 Madhur Ahuja 发布的链接( http://www.webskaper.no/wst/creatingasingleinstanceapplicationinc-aspx/ ) - 在此处复制(代码项目解决方案对我隐藏)。
重要的一点是保持互斥锁直到过程完成(我猜很明显)。
bool createdNew;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
{
if (createdNew) {
// process
}
else {
// in my case, quietly exit
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.