我在C#中有一个控制台应用程序,我想限制我的应用程序一次只运行一个实例。我如何在C#中实现这一目标?
答案 0 :(得分:46)
我会使用Mutex
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
}
}
答案 1 :(得分:32)
如果您决定使用Mutex用于此目的,您应该注意一些陷阱:
如果要将应用程序限制为每台计算机一个实例(即每个登录用户不是一个),那么您需要使用前缀Global\
开头的互斥锁名称。如果您不添加此前缀,操作系统将为每个用户创建一个不同的互斥锁实例。
如果您在启用了UAC的Windows Vista或更高版本的计算机上运行,并且当前的应用程序实例有可能以管理员身份运行,那么下一个实例将无法检测到它,您将获得权限异常。为避免这种情况,您需要在创建Mutex时为其指定一组不同的权限。
答案 2 :(得分:18)
有很多方法,例如 -
每个都在下面演示:
http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
http://www.codeproject.com/KB/cs/restricting_instances.aspx
http://www.codeproject.com/KB/cs/singleinstance.aspx
每个都有其优点和缺点。但我相信创建互斥锁是最好的。
答案 3 :(得分:3)
添加这个答案,因为以前的那些在使用.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核心特定问题上:Single instance dotnetcore cli app on linux
答案 4 :(得分:2)
这是一个适合我的解决方案
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;
}
然后我在程序启动时检查此方法的输出。
答案 5 :(得分:0)
对我来说最直接的答案,如下所示,取自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
}
}