我有两个应用程序,一个 WinForms 应用程序和一个 Windows 服务,它们都将在同一台机器上运行。我希望 WinForms 应用程序能够可靠地检测服务何时运行。我可以完全控制这两个应用程序的设计和实现。
我的第一个想法是使用Mutex,由服务实例化并由 WinForms 应用程序检测到。
有更好的设计吗?
K. Scott Allen 有一篇很好的文章,介绍了为此目的使用 Mutex 以及您在使用 GC 时会遇到的问题。
如果我只想让应用程序的一个实例在机器上的所有会话中运行,我可以将命名互斥锁放入带有前缀“Global\”的全局命名空间中。
[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());
}
}
编辑:
将字符串文字更改为使用转义的反斜杠而不是@
,因此语法荧光笔不喜欢逐字字符串。
互斥锁是要走的路。它比使用进程名称等要脆弱得多。
但是,您需要确保 Mutex 没有被垃圾回收。在服务的情况下(它是事件驱动的,而不是有一个运行到完成的“主”方法),最明智的做法可能是将它放在一个静态变量中。
服务停止时处理互斥锁,因此您无需等待完成或类似的事情。
您可以使用 Mutex,但也可以使用ServiceController
该类。这将允许您查明该服务是否已安装,如果已安装但未启动,则在适用时启动它。
http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller_members.aspx
您可以在服务上实现一些“连接测试”功能。我不知道这是否会满足您的要求。在 winforms 启动时,可以调用该服务查看它是否处于活动状态。您可以使用简单的 WCF 合同公开服务。
希望这可以帮助...
作为替代方案,您的 WinForms 应用程序可以检查正在运行的服务列表以查看该服务是否正在运行。