我正在尝试使用互斥方法只允许我的应用程序的一个实例运行。也就是说 - 我只想为一台机器上的所有用户提供最多一个实例。我已经阅读了关于这个问题的各种其他线程,解决方案看起来很简单,但在测试中我不能让我的第二个实例不能运行。这是我的代码......
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// check that there is only one instance of the control panel running...
bool createdNew = true;
using (Mutex instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew))
{
if (!createdNew)
{
Application.Current.Shutdown();
return;
}
}
base.OnStartup(e);
}
}
答案 0 :(得分:33)
您也使用相同的方法处理互斥锁,因此互斥锁仅在方法持续时间内存在。将互斥锁存储在静态字段中,并在应用期间保持活动状态。
答案 1 :(得分:28)
这是我的新代码,答案由@Willem van Rumpt(和@OJ)提供......
public partial class App : Application
{
private Mutex _instanceMutex = null;
protected override void OnStartup(StartupEventArgs e)
{
// check that there is only one instance of the control panel running...
bool createdNew;
_instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew);
if (!createdNew)
{
_instanceMutex = null;
Application.Current.Shutdown();
return;
}
base.OnStartup(e);
}
protected override void OnExit(ExitEventArgs e)
{
if(_instanceMutex != null)
_instanceMutex.ReleaseMutex();
base.OnExit(e);
}
}
答案 2 :(得分:4)
您在创建互联网并进行测试后立即销毁互斥锁。您需要在应用程序的生命周期内保持Mutex引用处于活动状态。
使Mutex成为Application类的成员/字段。 当应用程序关闭时释放互斥锁。
答案 3 :(得分:3)
作为扩展样本:
public static class Extension
{
private static Mutex mutex;
public static bool IsOneTimeLaunch(this Application application, string uniqueName = null)
{
var applicationName = Path.GetFileName(Assembly.GetEntryAssembly().GetName().Name);
uniqueName = uniqueName ?? string.Format("{0}_{1}_{2}",
Environment.MachineName,
Environment.UserName,
applicationName);
application.Exit += (sender, e) => mutex.Dispose();
bool isOneTimeLaunch;
mutex = new Mutex(true, uniqueName, out isOneTimeLaunch);
return isOneTimeLaunch;
}
}
App类:
protected override void OnStartup(StartupEventArgs e)
{
if (this.IsOneTimeLaunch())
{
base.OnStartup(e);
}
else
{
this.Shutdown();
}
}
答案 4 :(得分:1)
我可以建议一种更清晰的方法,它也会引入覆盖WPF应用程序中Main方法的有用概念。此外,如果使用您的解决方案,您可以查看任务管理器,您会注意到新实例实际上已达到执行状态(您可以看到在任务列表中创建的新进程),然后突然关闭。在随后的帖子中提出的方法也将避免这种缺点。 http://blog.clauskonrad.net/2011/04/wpf-how-to-make-your-application-single.html
答案 5 :(得分:1)
我被告知要在我们已经开发的WPF应用程序上实现这种互斥方法。使用我发现的OnStart()
覆盖问题的工作是在
App.g.cs
此文件位于
obj\x86\debug\
并包含main()
函数,因此您只需将这段代码放在主函数中即可。
bool isOnlyInstance = false;
Mutex m = new Mutex(true, @"WpfSingleInstanceApplication", out isOnlyInstance);
if (!isOnlyInstance)
{
MessageBox.Show("Another Instance of the application is already running.",
"Alert",
MessageBoxButton.OK,
MessageBoxImage.Exclamation);
return;
}
GC.KeepAlive(m);
但为此,您需要将app.xaml的BUILD ACTION
设置为ApplicationDefinition
注意:这可能不是最佳方式,因为我是初学者。 (请告诉我是否有什么要改变的地方)
答案 6 :(得分:0)
我是通过此链接完成此操作,只需在App.Xaml.cs中添加给定的类和一行 http://wpfsingleinstance.codeplex.com/
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
WpfSingleInstance.Make(); //added this is the function of that class
base.OnStartup(e);
}
}