在.net中创建单实例应用程序的最佳方法是什么?

时间:2009-07-17 19:54:33

标签: c# .net design-patterns

  

可能重复:
  What is the correct way to create a single instance application?
  Prevent multiple instances of a given app in .NET?

我是否检查是否存在具有相同名称的其他进程? (如果用户没有这样的权限怎么办?)

将文件写入磁盘并在退出前将其删除? (异常终止怎么办?)

这样做的最佳做法是什么?

5 个答案:

答案 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(我的首选方式)
  • 使用Mutex(位更复杂)
  • 检查具有相同详细信息的流程(我不喜欢这个)

有关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
  • 每台机器

我有一个类可用于强制每个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为您提供了一种在不依赖进程名称的情况下识别流程实例的方法。