阻止.NET中给定应用程序的多个实例?
在.NET中,阻止一个应用程序的多个实例同时运行的最佳方法是什么?如果没有"最佳"技术,那么每种解决方案都需要考虑哪些注意事项?
解决方案
http://en.csharp-online.net/Application_Architecture_in_Windows_Forms_2.0Single-Instance_Detection_and_Management
本文仅说明如何创建一个Windows应用程序,该应用程序可以控制其实例数或者仅运行单个实例。这是业务应用程序的非常典型的需求。已经有很多其他可能的解决方案来控制此问题。
http://www.openwinforms.com/single_instance_application.html
Hanselman发表了有关使用Microsoft.VisualBasic程序集的WinFormsApplicationBase类进行此操作的文章。
http://www.codeproject.com/KB/cs/SingleInstancingWithIpc.aspx
我们必须使用System.Diagnostics.Process。
检出:http://www.devx.com/tips/Tip/20044
通常,它是使用一个名为Mutex的文件完成的(使用新的Mutex(" your app name",true)并检查返回值),但是Microsoft.VisualBasic.dll中也有一些支持类可以为我们完成此操作。
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1) { AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn); return; }
在为可执行文件创建项目时,使用Visual Studio 2005或者2008,在"应用程序"面板内的属性窗口上,有一个名为"创建单实例应用程序"的复选框,我们可以激活该复选框以将其转换为单实例应用程序。
这是我正在谈论的窗口的捕获:
这是一个Visual Studio 2008 Windows应用程序项目。
使用Mutex。上面使用GetProcessByName的示例之一有很多警告。这是一篇关于该主题的好文章:
http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx
[STAThread] static void Main() { using(Mutex mutex = new Mutex(false, "Global\" + appGuid)) { if(!mutex.WaitOne(0, false)) { MessageBox.Show("Instance already running"); return; } Application.Run(new Form1()); } } private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
到目前为止,似乎已经建议了3种基本技术。
- 从Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase类派生并将IsSingleInstance属性设置为true。 (我认为这里需要说明的是,这不适用于WPF应用程序,对吗?)
- 使用命名的互斥锁并检查它是否已经创建。
- 获取正在运行的进程的列表,并比较这些进程的名称。 (这有一个警告,要求进程名称相对于在给定用户计算机上运行的任何其他进程是唯一的。)
有什么需要注意的事项吗?
这是我们需要确保仅运行一个实例的代码。这是使用命名互斥锁的方法。
public class Program { static System.Threading.Mutex singleton = new Mutex(true, "My App Name"); static void Main(string[] args) { if (!singleton.WaitOne(TimeSpan.Zero, true)) { //there is already another instance running! Application.Exit(); } } }
使用VB.NET!
不完全是 ;)
使用Microsoft.VisualBasic.ApplicationServices;
VB.Net的WindowsFormsApplicationBase为我们提供了" SingleInstace"属性,该属性确定其他实例,并且仅运行一个实例。
[STAThread] static void Main() // args are OK here, of course { bool ok; m = new System.Threading.Mutex(true, "YourNameHere", out ok); if (! ok) { MessageBox.Show("Another instance is already running."); return; } Application.Run(new Form1()); // or whatever was there GC.KeepAlive(m); // important! }
来自:确保.NET应用程序的单个实例
和:单实例应用程序互斥
与@Smink和@Imjustpondering相同的答案略有不同:
乔恩·斯基特(Jon Skeet)在C上的常见问题解答,找出GC.KeepAlive为何重要