可能重复:
What is the correct way to create a single instance application?
Prevent multiple instances of a given app in .NET?
我是否检查是否存在具有相同名称的其他进程? (如果用户没有这样的权限怎么办?)
将文件写入磁盘并在退出前将其删除? (异常终止怎么办?)
这样做的最佳做法是什么?
答案 0 :(得分:6)
您可以使用互斥锁。
bool firstInstance = true;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out firstInstance))
{
if (firstInstance)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
// Another instance loaded
}
}
答案 1 :(得分:0)
您可以使用Process
类的GetProcessesByName
方法查找具有相同名称的其他正在运行的进程,如果找到,则退出。
答案 2 :(得分:0)
通常,命名的互斥锁效果最好。以下是示例的链接:http://www.iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
答案 3 :(得分:0)
我依赖于你正在使用的技术。有很多解决方案,一些更适合WPF,一些适用于WinForms:
有关WindowsFormsApplicationsBase的更多信息:
http://www.openwinforms.com/single_instance_application.html
有关Mutex和检查进程的更多信息:
http://www.ravinderweb.com/page/Single-Instance-of-the-Application-using-C-Trick-and-Mutex.aspx
我不会使用文件,它容易出错,并且没有文件访问甚至可能导致程序中出现例外,即使它不是您应用程序的关键部分。
答案 4 :(得分:0)
有几种方法可以做到这一点,所有这些都有其优点和缺点,谷歌搜索会给你很多讨论。
您描述的方法有您提到的弱点。此外,您还需要考虑您希望实例的独特之处:
每台机器
我有一个类可用于强制每个WindowStation for Windows Forms应用程序的单个实例。基本上它使用P / Invoke在启动期间执行以下操作,使用互斥锁防止竞争条件:
定义固定的唯一字符串以标识您的应用(例如GUID)
获取名称来自您的唯一字符串的互斥锁。
使用P / Invoke调用EnumWindows枚举所有主窗口。
在EnumWindows回调中,依次在每个窗口上使用P / Invoke调用GetProp,将窗口句柄和您的唯一值作为参数传递。如果GetProp检测到具有唯一键的窗口(即应用程序的另一个实例),请将其激活(PostMessage(... SC_RESTORE ...),SetForegroundWindow,SetFocus),然后退出新实例。
如果枚举所有窗口而未找到上一个实例,请使用P / Invoke调用SetProp为应用程序的主窗体窗口句柄设置唯一值。
释放互斥锁并继续启动。
在我的用例中,这个解决方案比在进程的生命周期内简单地持有互斥锁更好,因为如果用户启动第二个实例而不是仅退出,它提供了激活前一个实例的方法。使用GetProp / SetProp为您提供了一种在不依赖进程名称的情况下识别流程实例的方法。