How to get the ServiceName

  • Thread starter Thread starter Jan Nielsen
  • Start date Start date
J

Jan Nielsen

I'm implementing a windows service using C# and dotnet. This service must be
able to be registered multiple times, and based on it's servicename I would
like to lookup parameters for the current instance in registry.
I think
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\myService\Parameters
would be the logical place to store these parameters. But I can't seem to
find a way to retrieve the servicename of the current instance of my
service.

I believe that if I had written this service in C, I could get the
servicename as it's passed as the first argument to the ServiceMain
function.
Is there a way to retrieve this information in a C# service ???

I've allready tried to to get this information from the arguments passed to
the OnStart function, but it seems like the first argument has been stripped
away.


Thanks in advance,
Jan Nielsen
 
No, I don't think so. ServiceBase.ServiceName is initially an empty string
which it set to a hardcoded value (default "Service1").
I guess the value passed to ServiceMain by SCM is the name that the service
is registered with in the registry.

I believe the two values must match exactly when you have several services
in the same process. In my case I register the the same exe-file multiple
times, which makes it impossible for the two values to match in all
instances.


Kind regards,
Jan Nielsen
 
Hi Jan,

Thanks for your posting. As for the get ServiceName prorblem you mentioned,
here is some of my understandings:

When you build a NTService via .net. In its intaller , it will hardcode a
ServcieName(unique) and a DisplayName(MAYBE NOT unique)

such as
====================
this.serviceInstaller1.DisplayName = "MyNTService1\'s DisplayName";
this.serviceInstaller1.ServiceName = "MyNTService1";
this.serviceInstaller1.StartType =
System.ServiceProcess.ServiceStartMode.Automatic;
============================
and this ServiceName will identify this serviceInstance under the
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ registry and also in
the system's SCM.
Also, the ServiceBase.DisplayName and ServiceController.ServiceName
property also means this value.

And the DisplayName is the just the User Friendly DisplayName in the SCM.
(the ServiceController.DisplayName means this value)

So is the "ServiceName" you want to get means the "DisplayName" ? If so ,
we can use the ServiceController.GetServices() to get all the
localmachine's installed services and get the running service via its
ServiceName property, then you can use the ServiceController.DisplayName to
access the user friendly name.

For example:

#NOTE that I've aslo try using the System.Environment.CommandLine to get
the commandline arguments of the service process, but it just contains the
exe file's path , not the ServiceName we want, you can also try it to
verify this.
===============================
protected override void OnStart(string[] args)
{
StreamWriter sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory+
"\\" + "log.txt",true,System.Text.Encoding.UTF8);

try
{

sw.WriteLine(" ");
sw.WriteLine("------start event--------");
sw.WriteLine("ServiceName: " + this.ServiceName);

ServiceController[] services = ServiceController.GetServices();
foreach(ServiceController sc in services)
{
if(sc.ServiceName == this.ServiceName)
{
sw.WriteLine("DisplayName: " + sc.DisplayName);
sw.WriteLine("ServiceType: " + sc.ServiceType.ToString());
}
}

sw.WriteLine("Start at: " + DateTime.Now.ToString("YYYY-MM-DD
HH:MM:SSfffffzzz"));

sw.WriteLine("CommandLine: " + System.Environment.CommandLine);

}
finally
{
sw.Close();
}

}
==================================

Hope this helps.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Hi Steven,

Thanks for your posting and trying to help, but unfortunately not exactly
what I was looking for.

I know the difference between the ServiceName and DisplayName, and it is the
ServiceName I need as I want to lookup some parameters in the registry.
I've not looked at the ServiceInstaller yet. So far I'm just registering my
service using the SC.exe utility.
With SC I can register my service multiple times, ex:
sc.exe create ServiceName1 binPath= D:\myservice.exe
sc.exe create ServiceName2 binPath= D:\myservice.exe

When I start the service "ServiceName1" I would like it to find it's
parameters in
HKLM\SYSTEM\CurrentControlSet\Services\ServiceName1\Parameters.
This way I can register my service as many time I want to, and still each
instance can have it's own configuration.

I got this idea from the old NT4 ressource kit utility SRVANY.EXE. This is a
service wrapper that can start any application that is not made as a real
service. Srvany can be registered with any name as long as it unique in the
system, and still it's able to lookup the value
HKLM\SYSTEM\CurrentControlSet\Services\"ServiceName"\Parameters\Application
to find out which application it should start.
This is exactly what I want my service to do, but I think this servicename
is delivered by the SCM to the ServiceMain function which I believe is
handled by the .net framework.

I found this other posting on the net:
http://www.dotnettalk.net/Receive_ServiceName_as_Argument_using_SCM-6151428-1292-a.html
I seems to be the exact same problem.
The suggested solution, as I understand it, is to put the servicename at the
end of the ImagePath in registry, to have it passed to the executable as an
ordinary argument. Within the service this can be read as the second
argument (the path to the executable is the first argument).
I think it could be registered somewhat like this:
sc.exe create ServiceName1 binPath= "D:\myservice.exe ServiceName1"

This is probably working, but requires the service to be registered in a
rather special way. I would like my service to be able to retrieve the real
servicename and not some argument. And I think SRVANY.exe proves it can be
done, the question is whether it can be done in a dotnet service.


Kind regards,
Jan Nielsen
 
Hi Jan,

Thanks for your followup. From your further description, I've got the your
concerns on this problem. However, based on my research, there seems hasn't
such a means to get the info in a .net based nt Service. For examle, if you
have a service class compiled into Servicecls.exe. Then, you use sc.exe
or .net installer to install it into SCM twice(with different ServiceName).
Then, when you start either one in the SCM, the
Servicecls.exe will be launched, but in the servicecls.exe 's Main
function, we haven't any means to determine which one in the SCM is
started.
I think currently, the means you mentioned that appending the ServiceName
as a commandline paramter in the execute path maybe a possbile workaround.
Otherwise, we may need to provide different execute path for exe file for
the different services.

Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Back
Top