我已经看到了有关使用WPF创建单个实例应用程序的所有其他问题,我选择使用此处所述的Microsoft方法:https://codereview.stackexchange.com/a/25667
这很好用,但现在我想在这个应用程序上使用Caliburn.Micro,这段代码与caliburn不兼容。
如何使用caliburn micro创建单个实例wpf应用程序?
要求非常简单:.net 4.5,每个用户会话只有一个应用程序实例
由于
答案 0 :(得分:3)
我在main方法中使用named mutex,如果互斥锁已经存在,则会显示一个对话框。
答案 1 :(得分:2)
如果有人遇到相同的问题,我想澄清步骤。
首先,您必须更改程序入口点发生的情况。如其他提到的那样,用作WPF程序入口点的Main()函数是自动生成的( App.g.i.cs );因此,我们必须以某种方式对其进行控制。如this answer中所述,有几种方法可以这样做。我个人更喜欢Third Approach:
在您的项目中包括另一个定义Main方法的类,如下所示:
class Startup
{
[STAThread]
public static void Main()
{
// Your single instance control (shown in below code)
...
}
}
标识您要应用程序用作入口点的主类。这可以通过项目属性来完成(在“解决方案资源管理器”中选择了项目时,右键单击项目> properties。在“应用程序”选项卡中,从下拉菜单中修改“启动对象”属性:
第二,,您必须确定一种机制来知道您的程序是否正在运行多次。有几种方法可以做到这一点(以及其他提到的答案)。我更喜欢的是这样:
...
// Your single instance control:
bool firstInstance = true;
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "some_unique_name_that_only_your_project_will_use", out firstInstance);
if (firstInstance)
{
// Everything that needs to be done in main class, for example:
YourProject.App app = new YourProject.App();
app.InitializeComponent();
app.Run();
}
else
{
// Your procedure for additional instances of program
MessageBox.Show("Another instance of this application is already running.");
}
即使在Caliburn.Micro
控制程序之前,这两个步骤也是实现目标的最简单方法之一。
答案 2 :(得分:0)
我很难在OnStartup()方法中尝试此操作。 基本上,您想创建一个Main方法(请参见No Main() in WPF?)并使用互斥体包装内容(请参见What is a good pattern for using a Global Mutex in C#?)
我的看起来像这样:
class SingleGlobalInstance : IDisposable
{
public bool _hasHandle = false;
Mutex _mutex;
private void InitMutex()
{
string appGuid = "My App Name"; //((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value;
string mutexId = string.Format("Global\\{}", appGuid);
_mutex = new Mutex(false, mutexId);
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
_mutex.SetAccessControl(securitySettings);
}
public SingleGlobalInstance(int timeOut)
{
InitMutex();
try
{
if(timeOut < 0)
_hasHandle = _mutex.WaitOne(Timeout.Infinite, false);
else
_hasHandle = _mutex.WaitOne(timeOut, false);
if (_hasHandle == false)
{
MessageBox.Show("Another instance is already running");
System.Windows.Application.Current.Shutdown();
}
}
catch (AbandonedMutexException)
{
_hasHandle = true;
}
}
public void Dispose()
{
if (_mutex != null)
{
if (_hasHandle)
_mutex.ReleaseMutex();
_mutex.Close();
}
}
}
我的App.xaml.cs包含:
[STAThread]
public static void Main()
{
using (new SingleGlobalInstance(1000))
{
var application = new App();
application.InitializeComponent();
application.Run();
}
}