在 .net 中制作单实例应用程序的最佳方法是啥? [复制]

Posted

技术标签:

【中文标题】在 .net 中制作单实例应用程序的最佳方法是啥? [复制]【英文标题】:What is the best way to make a single instance application in .net? [duplicate]在 .net 中制作单实例应用程序的最佳方法是什么? [复制] 【发布时间】:2009-07-17 19:54:33 【问题描述】:

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

我是否检查是否存在另一个同名进程? (如果用户没有权限怎么办?)

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

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

【问题讨论】:

可能重复:***.com/questions/19147/… 多次重复:***.com/questions/19147/…***.com/questions/93989/…***.com/questions/906100/… 【参考方案1】:

您可以使用互斥锁。

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
    

【讨论】:

这里的using语句很重要。始终将 Mutex 与: using 语句或 GC.KeepAlive(..) 或使 Mutex 静态结合。你想防止垃圾收集器清理你的互斥锁。 WindowsFormsApplicationsBase 仍然是我的首选方法。 紧凑的框架会是什么?【参考方案2】:

您可以使用Process 类的GetProcessesByName 方法查找另一个正在运行的同名进程,如果找到则退出。

【讨论】:

【参考方案3】:

通常,命名互斥体效果最好。这是示例的链接:http://www.iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx

【讨论】:

【参考方案4】:

我取决于您使用的技术。有很多解决方案,有的更适合 WPF,有的更适合 WinForms:

WindowsFormsApplicationsBase(我的首选方式) 使用互斥体(稍微复杂一点) 检查具有相同细节的进程(我不喜欢这个)

有关 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

我不会使用文件,它很容易出错,并且没有文件访问权限甚至可能导致程序出现异常,即使它不是应用程序的关键部分。

【讨论】:

【参考方案5】:

有几种方法可以做到这一点,所有这些都有其优点和缺点,谷歌搜索会给你很多关于它的讨论。

你描述的方法有你提到的弱点。您还需要考虑您希望您的实例有多独特:

每个 WindowStation

每台机器

我有一个类可用于为 Windows 窗体应用程序的每个 WindowStation 强制单个实例。基本上它在启动期间使用 P/Invoke 执行以下操作,使用 Mutex 防止竞争条件:

定义一个固定的唯一字符串来标识您的应用程序(例如 GUID)

获取一个互斥体,其名称来源于您的唯一字符串。

使用 P/Invoke 调用 EnumWindows 以枚举所有主窗口。

在 EnumWindows 回调中,依次在每个窗口上使用 P/Invoke 调用 GetProp,将窗口句柄和您的唯一值作为参数传递。如果 GetProp 检测到具有您的唯一键的窗口(即您的应用程序的另一个实例),请激活它(PostMessage(...SC_RESTORE...)、SetForegroundWindow、SetFocus),然后退出您的新实例。

李>

如果您枚举所有窗口而没有找到以前的实例,请使用 P/Invoke 调用 SetProp 为您的应用程序的主窗体窗口句柄设置您的唯一值。

释放互斥锁并继续启动。

在我的用例中,这个解决方案比简单地在进程的生命周期中保持一个互斥锁更好,因为它提供了一种在用户启动第二个实例而不是仅仅退出时激活前一个实例的方法。使用 GetProp/SetProp 为您提供了一种无需依赖流程名称即可识别流程实例的方法。

【讨论】:

以上是关于在 .net 中制作单实例应用程序的最佳方法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

对于 asp.net mvc Web 应用程序,将文本文件存储到 Sql Server 数据库中的最佳方法是啥?

创建单页应用程序 React JS 的最佳方法是啥? [关闭]

在同一台机器上的 .NET 应用程序之间复制对象的最佳方式是啥? [关闭]

在 .NET Core 2 Web Api 中验证 JWT 后获取用户数据的最佳做法是啥?

在 ASP.NET 应用程序中捕获所有异常的最佳方法是啥?

制作动画(flash)的最佳方法是啥