How to install a windows service programmatically

Discussion in 'Microsoft C# .NET' started by Bodo, Feb 17, 2009.

  1. Bodo

    Bodo Guest

    Hi,
    I'm trying to build my own class that inherits from
    System.Configuration.Install.Installer to build my own functionality of
    installing a windows service.
    However I'm struggeling with the install method:

    public virtual void Install( IDictionary stateSaver);

    I can't find any clues on how to specify stateSaver when calling
    Install(stateSaver) method.

    Also I' missing any class properties to state the path and name of the
    application to run as a service.

    Has anyone managed successfully to build his own custom class that
    registeres a windows service with c# using .net framework?

    TIA
    Bodo

    --
    Thanks in advance
    Bodo
     
    Bodo, Feb 17, 2009
    #1
    1. Advertisements

  2. Bodo wrote:
    > I'm trying to build my own class that inherits from
    > System.Configuration.Install.Installer to build my own functionality of
    > installing a windows service.
    > However I'm struggeling with the install method:
    >
    > public virtual void Install( IDictionary stateSaver);
    >
    > I can't find any clues on how to specify stateSaver when calling
    > Install(stateSaver) method.
    >

    There's no official documentation on this that I'm aware of, but I do happen
    to know how this works. In any case, this part is very simple: "stateSaver"
    can simply be empty initially.

    > Also I' missing any class properties to state the path and name of the
    > application to run as a service.
    >
    > Has anyone managed successfully to build his own custom class that
    > registeres a windows service with c# using .net framework?
    >

    *raises hand*

    In my case, it was a requirement that the installation parameters (service
    name, display name etc.) be part of the configuration file, so a single
    service could be installed multiple times under different names. (I don't
    recommend this setup in general, by the way, as it can lead to an explosion
    of services; a much better approach is to build one service that can handle
    multiple workloads through configuration.)

    Your Install() method should look somewhat like this:

    public override void Install(IDictionary stateSaver) {
    // There is only one service
    ServiceInstaller serviceInstaller = new ServiceInstaller();
    string serviceName = ConfigurationManager.AppSettings["ServiceName"];
    if (string.IsNullOrEmpty(serviceName)) throw new
    ConfigurationErrorsException("Missing 'ServiceName' setting in <appSettings>.");
    serviceInstaller.ServiceName = serviceName;
    string displayName = ConfigurationManager.AppSettings["DisplayName"];
    if (displayName != null) serviceInstaller.DisplayName = displayName;
    string description = ConfigurationManager.AppSettings["Description"];
    if (description != null) serviceInstaller.Description = description;
    Installers.Add(serviceInstaller);
    base.Install(stateSaver);
    }

    ServiceInstaller does the heavy lifting for you. You can take the settings
    from "stateSaver" instead of the configuration file. You can invent your own
    keys for this -- I recommend using a prefix so you don't clash with the
    settings the framework is going to be storing there.

    Sample use of your project installer:

    Hashtable savedState = new Hashtable();
    projectInstaller.Context = new InstallContext(null, args);
    projectInstaller.Context.Parameters["AssemblyPath"] =
    Process.GetCurrentProcess().MainModule.FileName;
    projectInstaller.Install(savedState);

    The "AssemblyPath" parameter is used by ServiceInstaller to... well, you can
    figure this one out, I'm sure. :)

    --
    J.
     
    Jeroen Mostert, Feb 18, 2009
    #2
    1. Advertisements

  3. Bodo

    Bodo Guest

    "Jeroen Mostert" wrote:

    > Bodo wrote:
    > > I'm trying to build my own class that inherits from
    > > System.Configuration.Install.Installer to build my own functionality of
    > > installing a windows service.
    > > However I'm struggeling with the install method:
    > >
    > > public virtual void Install( IDictionary stateSaver);
    > >
    > > I can't find any clues on how to specify stateSaver when calling
    > > Install(stateSaver) method.
    > >

    > There's no official documentation on this that I'm aware of, but I do happen
    > to know how this works. In any case, this part is very simple: "stateSaver"
    > can simply be empty initially.
    >
    > > Also I' missing any class properties to state the path and name of the
    > > application to run as a service.
    > >
    > > Has anyone managed successfully to build his own custom class that
    > > registeres a windows service with c# using .net framework?
    > >

    > *raises hand*
    >
    > In my case, it was a requirement that the installation parameters (service
    > name, display name etc.) be part of the configuration file, so a single
    > service could be installed multiple times under different names. (I don't
    > recommend this setup in general, by the way, as it can lead to an explosion
    > of services; a much better approach is to build one service that can handle
    > multiple workloads through configuration.)
    >
    > Your Install() method should look somewhat like this:
    >
    > public override void Install(IDictionary stateSaver) {
    > // There is only one service
    > ServiceInstaller serviceInstaller = new ServiceInstaller();
    > string serviceName = ConfigurationManager.AppSettings["ServiceName"];
    > if (string.IsNullOrEmpty(serviceName)) throw new
    > ConfigurationErrorsException("Missing 'ServiceName' setting in <appSettings>.");
    > serviceInstaller.ServiceName = serviceName;
    > string displayName = ConfigurationManager.AppSettings["DisplayName"];
    > if (displayName != null) serviceInstaller.DisplayName = displayName;
    > string description = ConfigurationManager.AppSettings["Description"];
    > if (description != null) serviceInstaller.Description = description;
    > Installers.Add(serviceInstaller);
    > base.Install(stateSaver);
    > }
    >
    > ServiceInstaller does the heavy lifting for you. You can take the settings
    > from "stateSaver" instead of the configuration file. You can invent your own
    > keys for this -- I recommend using a prefix so you don't clash with the
    > settings the framework is going to be storing there.
    >
    > Sample use of your project installer:
    >
    > Hashtable savedState = new Hashtable();
    > projectInstaller.Context = new InstallContext(null, args);
    > projectInstaller.Context.Parameters["AssemblyPath"] =
    > Process.GetCurrentProcess().MainModule.FileName;
    > projectInstaller.Install(savedState);
    >
    > The "AssemblyPath" parameter is used by ServiceInstaller to... well, you can
    > figure this one out, I'm sure. :)


    Hi Jeroen,
    thanks for pointing me to the right direction.
    Withthe use of AssemblyInstaller class I'm now able to install my assemby.
    However I'm missing one point, thats the Parameters required by the assembly
    Windows registry entry for that service has a "Parameters" Key.
    The assembly requires some string values that are stored in the Parameters
    Key.

    Are there any framework methods that allows me to add the values to the
    Parameters Key on installation process other than adding them by
    Microsoft.Win32.RegistryKey ?

    Again many thanks,
    Bodo
     
    Bodo, Feb 19, 2009
    #3
  4. Bodo

    Guest

    On Feb 19, 2:55 pm, Bodo <> wrote:
    > thanks for pointing me to the right direction.
    > Withthe  use of AssemblyInstaller class I'm now able to install my assemby.
    > However I'm missing one point, thats the Parameters required by the assembly
    > Windows registry entry for that service  has a "Parameters" Key.
    > The assembly requires some string values that are stored in the Parameters
    > Key.
    >
    > Are there any framework methods that allows me to add the values to the
    > Parameters Key on installation process other than adding them by
    > Microsoft.Win32.RegistryKey ?
    >

    There is as far as I know no way to do this other than by directly
    accessing the registry. This situation is the same in the unmanaged
    world -- there's no Win32 function for this. These parameters are not
    part of the service configuration itself, but of the SCM configuration
    -- it will pass these parameters to StartService(). Using start
    parameters for services is generally not recommended, as they offer
    limited room for configuration, require a service restart to pick up
    changes and will not be passed along if something calls StartService()
    directly. Some services use parameters as part of the path to the
    executable (where the parameter never changes and is not supposed to
    be user-editable) but I haven't tested if this works with
    ServiceInstaller as well.

    For managed services, there is no good reason to use the service
    parameters anyway -- that's what .config files are for. If you want to
    use parameters to be able to run the executable both as a service and
    as a regular console application, a better approach is to check
    Environment.Interactive from your Main and conditionally either call
    ServiceBase.Run() or Service.OnStart() directly.

    --
    J.
     
    , Feb 19, 2009
    #4
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Willy Denoyette [MVP]

    Re: Installing a Windows Service Programmatically

    Willy Denoyette [MVP], Sep 10, 2003, in forum: Microsoft C# .NET
    Replies:
    0
    Views:
    235
    Willy Denoyette [MVP]
    Sep 10, 2003
  2. Keith

    Programmatically stopping a Windows Service

    Keith, Nov 3, 2003, in forum: Microsoft C# .NET
    Replies:
    4
    Views:
    417
    Keith
    Nov 4, 2003
  3. David Sworder

    Install a Service Programmatically ?

    David Sworder, Feb 11, 2004, in forum: Microsoft C# .NET
    Replies:
    3
    Views:
    270
    Jeffrey Bradshaw
    Apr 20, 2004
  4. Guest

    programmatically removing a service

    Guest, May 13, 2005, in forum: Microsoft C# .NET
    Replies:
    2
    Views:
    151
    David Browne
    May 13, 2005
  5. sunil

    Installing a Windows Service programmatically

    sunil, Oct 5, 2006, in forum: Microsoft C# .NET
    Replies:
    7
    Views:
    449
    Willy Denoyette [MVP]
    Oct 7, 2006
Loading...

Share This Page