Reliably detecting that another of my applications

2019-01-26 02:10发布

问题:

I have two applications, a WinForms app and a Windows Service that will both run on the same machine. I want the WinForms app to reliably detect when the service is running. I have complete control over the design and implementation of both applications.

My first thought is to use a Mutex, instantiated by the Service and detectable by the WinForms App.

Is there a better design?

回答1:

Mutex is the way to go. It's a lot less fragile than using process names etc.

However, you need to make sure the Mutex isn't garbage collected. In the case of a service (which is event driven rather than having a "main" method which runs to completion), the most sensible way of doing this is probably to put it in a static variable.

Dispose of the mutex when the service stops, so you don't need to wait for finalization or anything like that.



回答2:

K. Scott Allen has a good write up on using a Mutex for this purpose and issues you'll run into with the GC.

If I want to have only one instance of the application running across all sessions on the machine, I can put the named mutex into the global namespace with the prefix “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());
   }
}

EDIT: Changed string literal to use escaped backslash instead of @, SO syntax highlighter didn't like the verbatim string.



回答3:

You could use a Mutex but you could also use the ServiceController class instead. This would allow you to find out if the service is installed, and if it is but isn't started then start it if applicable.

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



回答4:

You can implement some "Connection Test"-functionality on the service. I don't know if this will work for your requirements though. At the winforms startup, you can make a call to the service to see if it is alive. You can expose the service with a simple WCF contract.

Hope this helps...



回答5:

similar question [according to the answers there, you're on the right track]



回答6:

As an alternative, your WinForms app can check the list of running services to see if the service is running.