Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a Windows Service determine its ServiceName?

I've looked and couldn't find what should be a simple question:

How can a Windows Service determine the ServiceName for which it was started?

I know the installation can hack at the registry and add a command line argument, but logically that seems like it should be unnecessary, hence this question.

I'm hoping to run multiple copies of a single binary more cleanly than the registry hack.

Edit:

This is written in C#. My apps Main() entry point does different things, depending on command line arguments:

  • Install or Uninstall the service. The command line can provide a non-default ServiceName and can change the number of worker threads.
  • Run as a command-line executable (for debugging),
  • Run as a "Windows Service". Here, it creates an instance of my ServiceBase-derived class, then calls System.ServiceProcess.ServiceBase.Run(instance);

Currently, the installation step appends the service name and thread count to the ImagePath in the registry so the app can determine it's ServiceName.

like image 490
NVRAM Avatar asked Dec 03 '09 18:12

NVRAM


People also ask

How do I get a Servicename?

To find the service name and display name of each service on your system, type Get-Service . The service names appear in the Name column, and the display names appear in the DisplayName column. When you sort in ascending order by status value, Stopped services appear before Running services.

How do Windows services work?

Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface.

How do I install a Windows service with a different name?

You need to copy your service executable to a separate directory and use InstallUtil.exe to give it a different service name. From a command prompt, you'll need to use InstallUtil to install both instances of your service. For instructions on how to use InstallUtil, see Installer Tool (InstallUtil.exe).


1 Answers

From: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387024

Here is a WMI solution. Overriding the ServiceBase.ServiceMainCallback() might also work, but this seems to work for me...

    protected String GetServiceName()     {         // Calling System.ServiceProcess.ServiceBase::ServiceNamea allways returns         // an empty string,         // see https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387024          // So we have to do some more work to find out our service name, this only works if         // the process contains a single service, if there are more than one services hosted         // in the process you will have to do something else          int processId = System.Diagnostics.Process.GetCurrentProcess().Id;         String query = "SELECT * FROM Win32_Service where ProcessId = " + processId;         System.Management.ManagementObjectSearcher searcher =             new System.Management.ManagementObjectSearcher(query);          foreach (System.Management.ManagementObject queryObj in searcher.Get()) {             return queryObj["Name"].ToString();         }          throw new Exception("Can not get the ServiceName");     }  
like image 60
NVRAM Avatar answered Sep 24 '22 21:09

NVRAM