简体   繁体   English

使用 Caliburn.Micro 的单实例 WPF 应用程序

[英]Single instance WPF application using Caliburn.Micro

I've seen all the other questions regarding creating a single instance app using WPF and I've chosen to use the Microsoft's approach as described here: https://codereview.stackexchange.com/a/25667我已经看到了有关使用 WPF 创建单实例应用程序的所有其他问题,并且我选择使用 Microsoft 的方法,如下所述: https : //codereview.stackexchange.com/a/25667

This is working fine, but now I'd like to using Caliburn.Micro on this application and this code does not play well with caliburn.这工作正常,但现在我想在此应用程序上使用 Caliburn.Micro 并且此代码与 caliburn 不兼容。

How can I have a single instance wpf application using caliburn micro?如何使用 caliburn micro 拥有单实例 wpf 应用程序?

The requirement are quite simple: .net 4.5 and only one instance of the application per user session要求非常简单:.net 4.5 并且每个用户会话只有一个应用程序实例

Thanks谢谢

I use a named mutex in my main method and show a dialog if the mutex already exists.我在我的主要方法中使用了一个命名的互斥锁,如果互斥锁已经存在,则显示一个对话框。

Check this stack - WPF Single Instance Best Practices检查此堆栈 - WPF 单实例最佳实践

In case anyone is having the same issue, I want to clarify the steps.如果有人遇到同样的问题,我想澄清这些步骤。

First, you have to change what happens in program entry point.首先,您必须更改程序入口点中发生的事情。 As others mentioned, the Main() function that acts as an entry point to WPF programs is auto-generated ( App.gics );正如其他人提到的,作为 WPF 程序入口点的 Main() 函数是自动生成的 ( App.gics ); So we have to take control of it somehow.所以我们必须以某种方式控制它。 As mentioned in this answer , there are several ways to do so.正如在这个答案中提到的,有几种方法可以做到这一点。 Personally I prefer the Third Approach :我个人更喜欢第三种方法

Include another class in your project that defines the Main method as below:在您的项目中包含另一个定义 Main 方法的类,如下所示:

class Startup
{
    [STAThread]
    public static void Main()
    {
        // Your single instance control (shown in below code)
        ...
    }
}

Identify the class whose main you want the application to use as entry point.确定您希望应用程序将其 main 用作入口点的类。 This can be done via the project properties (right-click on your project >properties. or alt+enter while your project is selected in Solution Explorer).这可以通过项目属性来完成(在解决方案资源管理器中选择您的项目时,右键单击您的项目 > 属性。或 alt+enter)。 In the Application tab, modify the Startup object properties from the drop down:在应用程序选项卡中,从下拉列表中修改启动对象属性:

Second, you have to decide for a mechanism to know if your program is being run more than once.其次,您必须决定一种机制来了解您的程序是否被多次运行。 There are several ways to do that ( as the other answers mentioned ).有几种方法可以做到这一点(如提到的其他答案)。 The one I prefer is this:我更喜欢的是这个:

        ...
        // 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.");
        }

These two steps together are one of the easiest ways to achieve your goal, even before Caliburn.Micro takes control of your program.这两个步骤一起是实现目标的最简单方法之一,甚至在Caliburn.Micro控制您的程序之前。

I had difficulty attempting this in the OnStartup() method.我在 OnStartup() 方法中尝试这个有困难。 Basically, you want to create a Main method (see No Main() in WPF? ) and wrap the contents using the mutex (see What is a good pattern for using a Global Mutex in C#? )基本上,您想创建一个 Main 方法(请参阅WPF 中的 No Main()? )并使用互斥锁包装内容(请参阅在 C# 中使用全局互斥锁的好模式是什么?

Mine looked like this:我的看起来像这样:

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\\{{{0}}}", 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();

        }

    }

}

And my App.xaml.cs contained:我的 App.xaml.cs 包含:

    [STAThread]
    public static void Main()
    {
        using (new SingleGlobalInstance(1000))
        {
            var application = new App();
            application.InitializeComponent();
            application.Run();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用另一个应用程序实例和Caliburn.Micro从任务栏最大化WPF应用程序 - Maximize WPF application from the taskbar using another application instance and Caliburn.Micro WPF Caliburn.Micro - 在Singe Window应用程序中导航的最佳方式 - WPF Caliburn.Micro - Best way to navigate in Singe Window Application 在WPF中使用INotifyDataErrorInfo和嵌入式UserControl(与Caliburn.Micro)一起使用 - Using INotifyDataErrorInfo with embedded UserControl in WPF (with Caliburn.Micro) 使用WPF和Caliburn.Micro在视图中添加多个视图 - Add multiple views inside a view using WPF and Caliburn.Micro 如何使用 Caliburn.Micro MVVM 正确设置 WPF 文本框的样式? - How to properly style a WPF TextBox using Caliburn.Micro MVVM? 使用caliburn.micro wpf c#更改视图名称 - Change name of view using caliburn.micro wpf c# WPF / Caliburn.Micro-使用IDataErrorInfo进行输入验证 - WPF/Caliburn.Micro - Input Validation using IDataErrorInfo 如何使用caliburn.micro WPF抓取webbrowser.document - How to grab webbrowser.document using caliburn.micro WPF 使用Caliburn.Micro同时显示两个WPF窗口 - Display two WPF windows simultaneously using Caliburn.Micro 使用Caliburn.Micro MVVM WPF进行视图导航的建议 - Advice on Views navigation using Caliburn.Micro MVVM WPF
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM