确保只有一个应用程序实例

本文关键字:实例 应用程序 有一个 确保 | 更新日期: 2023-09-27 18:00:31

可能重复:
创建单实例应用程序的正确方法是什么?

我有一个Winforms应用程序,它通过以下代码启动一个启动屏幕:

Hide();
        bool done = false;
        // Below is a closure which will work with outer variables.
        ThreadPool.QueueUserWorkItem(x =>
                                  {
                                      using (var splashForm = new SplashScreen())
                                      {
                                          splashForm.Show();
                                          while (!done)
                                              Application.DoEvents();
                                          splashForm.Close();
                                      }
                                  });
        Thread.Sleep(3000);
        done = true;

以上内容在主窗体的codeehind中,并从加载事件处理程序调用。

但是,如何确保一次只加载一个应用程序实例?在主窗体的加载事件处理程序中,我可以检查进程列表是否在系统上(通过GetProcessesByName(…)),但有更好的方法吗?

正在使用。NET 3.5。

确保只有一个应用程序实例

GetProcessesByName是检查另一个实例是否正在运行的缓慢方法。最快和优雅的方法是使用互斥:

[STAThread]
    static void Main()
    {
        bool result;
        var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result);
        if (!result)
        {
            MessageBox.Show("Another instance is already running.");
            return;
        }
        Application.Run(new Form1());
        GC.KeepAlive(mutex);                // mutex shouldn't be released - important line
    }

还请记住,您提供的代码不是最好的方法。正如一条评论中所建议的那样,在循环中调用DoEvents()不是最好的主意。

static class Program
{
    // Mutex can be made static so that GC doesn't recycle
    // same effect with GC.KeepAlive(mutex) at the end of main
    static Mutex mutex = new Mutex(false, "some-unique-id");
    [STAThread]
    static void Main()
    {
        // if you like to wait a few seconds in case that the instance is just 
        // shutting down
        if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
        {
            MessageBox.Show("Application already started!", "", MessageBoxButtons.OK);
            return;
        }
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        finally { mutex.ReleaseMutex(); } // I find this more explicit
    }
}

关于一些唯一的id的一个注意事项->这在机器上应该是唯一的,所以使用类似于您的公司名称/应用程序名称的东西。

编辑:

http://sanity-free.org/143/csharp_dotnet_single_instance_application.html