Re: ServiceBase denies access to service name
- From: nickdu <nicknospamdu@xxxxxxxxxxxxxxxx>
- Date: Sun, 11 Jan 2009 10:39:01 -0800
I don't mind being educated on any misconceptions I have, but I don't think
you're correct on every point. The goal of what I'm trying to do is:
1. I've created a single managed service process that I want to use to
handle multiple services, each in their own process.
2. Since each service would be using the same binary and each would need its
own configuration, there needs to be some way for each service to have its
own configuration file. Similar to how web apps work I can envision some
service code create a new app domain and setting up the application config to
be <service name>.config.
#1 is easy to do in the unmanaged world because I have access to the command
line arguments and I'm pretty sure that the first command line argument is
the service name not the binary name. And unfortunately the .NET
implementation skips over the first command line argument.
--
Thanks,
Nick
nicknospamdu@xxxxxxxxxxxxxxxx
remove "nospam" change community. to msn.com
"Stephen Martin" wrote:
Hi,.
You seem to have a few misconceptions about .Net services and how the
ServiceName is set.
First of all you are misunderstanding the ServiceMainCallback and its
arguments. The arguments to ServiceMainCallback are not the command line
arguments of the executable but rather the arguments sent to the service
itself by the Service Control Manager. There is no service name argument, in
fact the arguments to ServiceMainCallback are almost always argCount = 0,
argPointer = null. These are the arguments sent to the OnStart method of
your service.
Even if these were the command line parameters arg[0] would be the name of
the executable not the service.
Also, this would not work for your purpose anyway since the
ServiceMainCallback is called by the SCM after ServiceBase.Run is called and
the ServiceName property has to be set before Run is called or the service
cannot properly connect to the SCM.
It is possible, and relatively easy, to run multiple named services using
the same service class but the names must be set in the Main method of the
service process before ServiceBase.Run is called. Your service class should
accept a name parameter in its constructor that is used to set the
ServiceName property.
You can then set up your service to run with a command line parameter that
is parsed in Main and sent to the service class in its constructor, each
named service would run in a different service process with a different
command line parameter. This, unfortunately, causes additional complexity
for installation and you may not want a separate executable for each
service.
Another method is to have a config file for the service executable that
contains the names of all the services in, say, its appSettings section.
This config file would be read in the Main method and a separate instance of
the service class would be created with each name and sent to the Run
method. This is easier to install and manage but many people do not go for
this for lack of isolation reasons.
If you wanted to go further and set up separate AppDomains for each service
you would do as above but your service class would just be a shell that
would spin up a worker thread and create a separate AppDomain into which
your real ServiceWork class would be loaded.
Hope this helps.
"nickdu" <nicknospamdu@xxxxxxxxxxxxxxxx> wrote in message
news:8A5E51C3-F8F4-4267-A299-EE7FFC0F5C5F@xxxxxxxxxxxxxxxx
It appears the ServiceBase class denies a derived class access to the
service
name. It does this in its ServiceMainCallback by the fact that it skips
over the first argument:
public unsafe void ServiceMainCallback(int argCount, IntPtr argPointer)
{
fixed (NativeMethods.SERVICE_STATUS* service_statusRef = &this.status)
{
string[] state = null;
if (argCount > 0)
{
char** chPtr = (char**) argPointer.ToPointer();
state = new string[argCount - 1];
for (int i = 0; i < state.Length; i++)
{
chPtr++;
state[i] = Marshal.PtrToStringUni(*((IntPtr*) chPtr));
}
}
.
.
.
Can this be fixed to either:
1. Provide the parameter in the args value. I assume this would break a
bunch of apps so it's probably not possible.
or
2. Process the service name argument (arg[0]) and set the ServiceName
property on the service object.
Actually the feature I'm trying to implement is one where I can have
multiple instances of the same service (different service names of course)
each with its own application configuration file. To accomplish this the
ServiceBase class could have created a new appdomain and run the service
component in that domain setting the app configuration file to the name of
the service, similar to how ASP.NET sets the app configuration to
web.config.
--
Thanks,
Nick
nicknospamdu@xxxxxxxxxxxxxxxx
remove "nospam" change community. to msn.com
- Follow-Ups:
- Re: ServiceBase denies access to service name
- From: Stephen Martin
- Re: ServiceBase denies access to service name
- Prev by Date: Re: Opening windows media video streams in .NET
- Next by Date: Stream based base64 encoding/decoding
- Previous by thread: LINQ Query Help
- Next by thread: Re: ServiceBase denies access to service name
- Index(es):
Relevant Pages
|