determine if executable being run by Service Control Manager

  • Thread starter Thread starter Dan Schullman
  • Start date Start date
D

Dan Schullman

Hello,

I've got some executables that need to run both as a Windows Service and
independently. How can I in my .NET code determine the environment/context
in which they're running?

For example, one executable is the service executable AND a CLI utility to
manage that service. Another needs to know the mode to figure out how to
handle logging (e.g., use EventLog or write to STDOUT).

By the way, I also noticed that contrary to the docs for ServiceBase.Run(),
it does NOT throw an exception when invoked from a command line program but
rather pops up a GUI error message and then simply returns, so the caller
presumably has no way to know that it failed.

Thanks,
Dan S.
 
Dan said:
Hello,

I've got some executables that need to run both as a Windows Service and
independently. How can I in my .NET code determine the environment/context
in which they're running?

For example, one executable is the service executable AND a CLI utility to
manage that service. Another needs to know the mode to figure out how to
handle logging (e.g., use EventLog or write to STDOUT).

By the way, I also noticed that contrary to the docs for ServiceBase.Run(),
it does NOT throw an exception when invoked from a command line program but
rather pops up a GUI error message and then simply returns, so the caller
presumably has no way to know that it failed.

Thanks,
Dan S.


If you know the name of the service, you can probably lookup in
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Service registry key. It
will have keys for each service installed. If you find it there, it is
installed as a service. Of course, if you can install this as a service
and can also run it (by double clicking or something).. you probably
need some sort of IPC messaging (A low tech way of writing to a shared
memory will also work fine)..
 
Girish,

Thanks for the feedback. However, I'm NOT trying to figure out if the
executable is INSTALLED as a service. I'm trying to figure out if an
executable that's installed as a service is being RUN as a service (vs. from
a command line, Windows Explorer, etc.). I also cannot assume that the
service will necessarily be running when I run the executable separately
from the command line.

--Dan S.
 
Dan said:
Girish,

Thanks for the feedback. However, I'm NOT trying to figure out if the
executable is INSTALLED as a service. I'm trying to figure out if an
executable that's installed as a service is being RUN as a service (vs. from
a command line, Windows Explorer, etc.). I also cannot assume that the
service will necessarily be running when I run the executable separately
from the command line.

--Dan S.
Oh..k,
If you have control on the code for the EXE, you can probably check
which entry point on the exe was called (ServiceMain) or (WinMain/main).
And respond to some sort of message (COM based or otherwise).

If you dont have the control over that, then you will have to do
OpenSCManager/OpenService/QueryServiceStatus calls to figure out if the
service is the one actually running or not.
 
Yep, we are writing the executable. It's a J# console application, so I
don't believe we have visibility to the entry points you mention (though
we're new to Windows development so you cold easily fool (or confuse) us!).
As far as we know, execution simply starts at 'main'.

Also, I just skimmed some of the MSDN library doc on QueryServiceStatus but
it seems like mostly it will tell me what the service is currently doing...
NOT whether the current process IS the service process. Essentially, I need
to know if the executable is spawned (or whatever the mechanism is) by the
Service Control Manager. Also, we're writing .NET code (though I believe the
ServiceController class would give me the same sort of info as the functions
you mentioned).

Thanks again,
Dan S.
 
Well, I know that that is how things are supposed to work in Win32 Api. As
you can see, I am more of a C++/Win32 guy getting immersed in C# world. So,
things get a little confusing sometimes.
Anyway, I suggested QueryConfigStatus because that would either respond,
i.e., that exe is running as a service or not, which case it is running as a
normal executable.. :)
Anyway, If you can specify more of what you are trying to do, by knowing
that its running as a service/not .. i might be able to help you better.
Sorry if I confused you..
 
Girish,

Allow me to try once more...

I've got some console application executables that can be invoked by me
directly (via a command prompt) or by the Service Control Manager (SCM). I
want them to behave differently depending on the context/mode in which
they're executing. For example, I want MyService.exe to implement the
service (and use the EventLog.WriteEntry) when run by the SCM but to provide
a means to query and otherwise manage the service (and use
Console.WriteLine) when run from the command line. The executable can be
running (or even just installed) as a service or not, INDEPENDENT of whether
the executable is also being run from the command line. For example, running
MyService.exe from the command line might tell me whether the service
implemented by MyService.exe is currently running, or I might use it to
install/start and stop/remove the service.

So I'd like my code to look something like the following:

public static void main( String[] args )
{
boolean runningInteractively = IsCurrentProcessAServiceProcess();
if ( runningInteractively )
{
//manage the service; use console output stream for messages
}
else
{
//invoke ServiceBase.Run() to load my service; use Event Log for
messages
}
}

Thanks,
Dan S.
 
Dan said:
Girish,

Allow me to try once more...

I've got some console application executables that can be invoked by me
directly (via a command prompt) or by the Service Control Manager (SCM). I
want them to behave differently depending on the context/mode in which
they're executing. For example, I want MyService.exe to implement the
service (and use the EventLog.WriteEntry) when run by the SCM but to provide
a means to query and otherwise manage the service (and use
Console.WriteLine) when run from the command line. The executable can be
running (or even just installed) as a service or not, INDEPENDENT of whether
the executable is also being run from the command line. For example, running
MyService.exe from the command line might tell me whether the service
implemented by MyService.exe is currently running, or I might use it to
install/start and stop/remove the service.

So I'd like my code to look something like the following:

public static void main( String[] args )
{
boolean runningInteractively = IsCurrentProcessAServiceProcess();
if ( runningInteractively )
{
//manage the service; use console output stream for messages
}
else
{
//invoke ServiceBase.Run() to load my service; use Event Log for
messages
}
}

Thanks,
Dan S.

Ok.. Couple of things I can think of.
1. If you implement OnStart() event and do stuff there, that might tell
you that you are started as a "service" and not as a regular executable.
It is called by SCM when the service is "started" by the OS or by
someone clicking Start.

2. For setting up stuff, you probably want to use ServiceInstaller class
anyway.
 
Back
Top