Tuesday, June 9, 2009

Get WindowService Executable Path In .NET

WindowService has a property called “Path to Executable” . This property contains path of window service that is going to execute. When you need this path in .NET Application there is no direct way to do it . You can not get it either via ServiceControler or any other way.

image 
To get that you need to read Registry. All information about all window service installed on machine storead at following location.
HKLM\SYSTEM\CurrentControlSet\Services.

C# Code to read Service Registry.

RegistryKey services = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services");
if (services != null)
{
object pathtoexecutable = services.OpenSubKey(<<ServiceName>>).GetValue("ImagePath");
}

In Above code replace <<ServiceName>> with your service name.

Also this is a registry operation so you need proper permission to read registry and apply any other registry operation at your own risk.

Give your comment or any new idea about this task.

4 comments:

Rafael S Rodrigues said...

I think that when we deal with dotnet, stating that "there is no way" is in most cases just wrong. "I couldn't figure out a way" would leave the readers of your post a chance of more googling instead of perhaps just giving up and resorting to sometimes more troubling approaches, like this one. There are so many functionalities in so many namespaces in dotnet... you could...

... Try:

System.Reflection.Assembly.GetExecutingAssembly().Location

or

AppDomain.CurrentDomain.BaseDirectory

It works in my services, since version 1.0 or 1.1 of the framework _if i can remember_.

Regards !

Rafael Rodrigues

dotnetstep said...

Hello,

In .NET we can get Executable path using
any of your suggestion.

But my article is about when we have requirement which executable file is service is using.

What ever you are using that is inside that window service application.

But i want list of all services running in machine and their executable file then you have to use registry.

Let me know your suggestion on that.

Thanks.

Rafael Rodrigues said...

Dude, if that is the case, you really should have specified better the goal of your article.

And yes, as a matter of fact, there is a better way than running tru registry keys:
Windows has many of those SO tables to inform you of many SO things. The cool thing is that you use the well-known SQL to ask him for what you need. Here is the one you want:

1. Import a reference to System.Management;

2. ManagementObjectSearcher mos = new
ManagementObjectSearcher( "SELECT PathName FROM Win32_Service WHERE Name = " ...

3. foreach( ManagementObject mo in mos.Get() )
{ Console.Writeline( Path.GetDirectoryName( mo[
"PathName" ].ToString() );
}

Just a sidenote: ManagementObject is a resource so you should enclose it's instanciation within using().

Hope it helps you out

dotnetstep said...

Hi,

You suggest one of the solution that is based on WMI. It may be possible that WMI is not install or not enabled on machine.

In windows sometime WMI call is blocked by firewall.

Thanks.