0

我有两个应用程序,一个 WinForms 应用程序和一个 Windows 服务,它们都将在同一台机器上运行。我希望 WinForms 应用程序能够可靠地检测服务何时运行。我可以完全控制这两个应用程序的设计和实现。

我的第一个想法是使用Mutex,由服务实例化并由 WinForms 应用程序检测到。

有更好的设计吗?

4

5 回答 5

7

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());
   }
}

编辑: 将字符串文字更改为使用转义的反斜杠而不是@,因此语法荧光笔不喜欢逐字字符串。

于 2009-06-10T12:28:36.423 回答
3

互斥锁是要走的路。它比使用进程名称等要脆弱得多。

但是,您需要确保 Mutex 没有被垃圾回收。在服务的情况下(它是事件驱动的,而不是有一个运行到完成的“主”方法),最明智的做法可能是将它放在一个静态变量中。

服务停止时处理互斥锁,因此您无需等待完成或类似的事情。

于 2009-06-10T12:26:59.953 回答
2

您可以使用 Mutex,但也可以使用ServiceController该类。这将允许您查明该服务是否已安装,如果已安装但未启动,则在适用时启动它。

http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller_members.aspx

于 2009-06-10T12:34:43.683 回答
1

您可以在服务上实现一些“连接测试”功能。我不知道这是否会满足您的要求。在 winforms 启动时,可以调用该服务查看它是否处于活动状态。您可以使用简单的 WCF 合同公开服务。

希望这可以帮助...

于 2009-06-10T12:29:41.260 回答
0

作为替代方案,您的 WinForms 应用程序可以检查正在运行的服务列表以查看该服务是否正在运行。

于 2009-06-10T12:29:21.930 回答