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

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

我有一个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; 

以上是主窗体的代码隐藏,并从加载事件处理程序调用。

但是,如何确保一次只加载一个应用程序实例? 在主窗体的load事件处理程序中,我可以检查进程列表是否在系统上(通过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 } } 

关于so​​me-unique-id – >的一个注意事项在机器上应该是唯一的,所以请使用类似公司名称/应用程序名称的内容。

编辑:

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