Drew
Drew

Reputation: 1347

How to check if the current executable already has a Windows service tied to it

I have a C# console application which users can download. When they run and set up the program, it installs a Windows service which then handles running the program. I want users to be able to download this application more than once, and create one Windows service for each downloaded program. I can allow this by making sure the program gives the service a unique name (otherwise an exception would be thrown saying the service already exists).

However, I don't want the user to be able to run the same instance of a downloaded executable multiple times and install the service over and over again. Only one service for each downloaded executable (i.e. one per bin directory, even though the executables are the same).

Before attempting to install the service, I want to check if the specific executable that is running already has a Windows service tied to it, in which case I don't go ahead with installing another one. Note that it has to be a more thorough check than just the executable name because all the programs the user downloads will have the same name. Since each executable will be in a different bin directory, could it be a check against the directory path?

Another option is to check the Windows service's name. The problem is knowing what name to check. If I hardcode the name of the service to be something like "MyService", then more than one service couldn't be created at all. If I make the service name unique by doing something like "MyService" + Guid.NewGuid(), then the name would be unique each time the same executable is run and so I wouldn't be able to check it that way. The only way I can think of making the service name unique per bin directory is to include something about the bin directory in the name, for example base64 encoding the directory path. But this might cause problems if the bin folder is moved around.

Upvotes: 1

Views: 257

Answers (1)

T McKeown
T McKeown

Reputation: 12857

A simple solution is to use a mutex. Similar to how you prevent multiple instances of an .exe

https://stackoverflow.com/a/819808/290187

Of course this requires the service to be running. You could query installed services via C#:

ServiceController[] services = ServiceController.GetServices();

Or you can always run 'regsvr32' and parse/review the output.

Or you embed a named pipes WCF service inside your service:

WCF named pipe minimal example

many options

Upvotes: 2

Related Questions