【问题标题】:WPF mutex for single app instance not working单个应用程序实例的 WPF 互斥锁不起作用
【发布时间】:2011-07-19 13:42:31
【问题描述】:

我正在尝试使用 mutex 方法只允许我的应用程序的一个实例运行。也就是说 - 我只希望一台机器上的所有用户最多有一个实例。我已经阅读了有关此问题的各种其他线程,解决方案似乎很简单,但在测试中我无法让我的第二个实例不运行。这是我的代码...

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);
    }
}

【问题讨论】:

    标签: c# wpf mutex


    【解决方案1】:

    您还在同一方法中处理互斥锁,因此互斥锁仅在方法的持续时间内存在。将互斥锁存储在一个静态字段中,并在您的应用程序期间保持活动状态。

    【讨论】:

    • 感谢@Willem van Rumpt(和@OJ)。这样可行。我错误地认为 Mutex 确实是幕后的东西,更多的是在系统级别,并且 Mutex 对象实例并不重要。我在下面包含了我的新代码以供将来参考...
    • @OJ:很高兴能站在“胜利”的一方进行变革:)
    • 为我工作。 :)
    【解决方案2】:

    这是我的新代码,答案由@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);
        }
    }
    

    【讨论】:

    【解决方案3】:

    在创建并测试 Mutex 后,您将立即销毁它。您需要在应用程序的整个生命周期内保持 Mutex 引用有效。

    使 Mutex 成为 Application 类的成员/字段。 当您的应用程序关闭时释放互斥锁。

    【讨论】:

      【解决方案4】:

      作为扩展示例:

      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;
          }
      }
      

      应用类:

          protected override void OnStartup(StartupEventArgs e)
          {
              if (this.IsOneTimeLaunch())
              {
                  base.OnStartup(e);
              }
              else
              {
                  this.Shutdown();
              }
          }
      

      【讨论】:

        【解决方案5】:

        我可以建议一种更简洁的方法,该方法还引入了在 WPF 应用程序中覆盖 Main 方法的有用概念。此外,如果使用您的解决方案查看任务管理器,您会注意到新实例实际上达到了执行状态(您可以看到在任务列表中创建了一个新进程)然后突然关闭。随后的帖子中提出的方法也将避免这个缺点。 http://blog.clauskonrad.net/2011/04/wpf-how-to-make-your-application-single.html

        【讨论】:

          【解决方案6】:

          有人告诉我在我们已经开发的 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

          注意:这可能不是最好的方法,因为我是初学者。 (如果有什么我应该改变的,请告诉我)

          【讨论】:

            【解决方案7】:

            我是从这个链接做的,只是在 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);
              }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-05-01
              • 1970-01-01
              • 2011-12-08
              • 2021-03-28
              • 1970-01-01
              • 1970-01-01
              • 2016-05-19
              • 1970-01-01
              相关资源
              最近更新 更多