20

We have a Windows Service application that can accept command line parameters like:

MyService -option 

So far, when we want to start the service with a parameter, we either do it manually from the Service Properties dialog (in the Start parameters box) or with the command

sc start MyService -option  

What we would like is a way to install the service "permanently" with this parameter, so that the users would just have to start/stop it without having to set the parameter each time.

BTW, adding the parameter in the ImagePath registry entry doesn't work, neither does installing like this:

MyService -option /install

Updated: Thank you for the answers so far which help me refine the question.
What I'd like to achieve is to set the parameter at the Service level itself (like with the properties) in case there are more than 1 service in the same executable. The binpath config option is merely updating the ImagePath entry in the registry. That cannot be service specific.

Francesca
  • 21,452
  • 4
  • 49
  • 90

9 Answers9

18
sc config MyService binPath= MyService.exe -option

Update

The individual service parameters are stored in the the registry at the key HKLM\SYSTEM\CurrentControlSet\Services\<serviceName>\Parameters. I'm not sure though how the parameters are passed to the service. I believe SCM reads these values then when it calls StartService it passes them to the ServiceMain callback.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • Equivalent to edit the ImagePath registry entry. Not specific to the service itself. But a good way to manage that entry anyway, thanks. – Francesca Sep 28 '09 at 22:34
  • Good try, but it does not seem to work... (at least not like with properties or sc start) – Francesca Sep 29 '09 at 01:31
  • StartService *does* pass as arguments to ServiceMain whatever is configured in the Service Properties 'Arguments' edit box from the services.msc snap in, that is documented in the spec. That should be good enough for you I believe. – Remus Rusanu Sep 29 '09 at 01:35
  • 5
    The spec for ServiceMain says that the parameters entered in that edit box are for when the user is starting the service ***manually***. They are not saved once the user has clicked OK, and they are not used when auto-starting services. – Aaron Klotz Jul 06 '10 at 02:02
  • 3
    Do not forget the quotes sc config MyService binPath= "MyService.exe option" – Jean Davy Jan 12 '17 at 07:29
  • 1
    If you're working in powershell, be sure to use "sc.exe" instead of "sc" which is an alias for Set-Content – Luke Dec 21 '22 at 14:11
3

How about putting the parameter in a config file?

Raj More
  • 47,048
  • 33
  • 131
  • 198
  • 3
    Wouldn't work if you want to host multiple services in the same .exe, as clarified in question update. Which config file do you choose? – Tim Sparkles Nov 17 '16 at 23:00
2

According to the ServiceBase.OnStart documentation:

The arguments entered in the console are not saved; they are passed to the service on a one-time basis when the service is started from the control panel. Arguments that must be present when the service is automatically started can be placed in the ImagePath string value for the service's registry key (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\). You can obtain the arguments from the registry using the GetCommandLineArgs method, for example: string[] imagePathArgs = Environment.GetCommandLineArgs();.

Rosberg Linhares
  • 3,537
  • 1
  • 32
  • 35
  • I tested it, it is not getting args from registry –  Nov 09 '16 at 10:30
  • 1
    @Desolator, in my case the service name is IISLogMonitor. So I changed the string value _HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISLogMonitor\ImagePath_ to _C:\Program Files\IIS Log Monitor\PowershellScriptAsService.exe" -LogName "IIS Log Monitor" -ScriptPath "C:\Program Files\IIS Log Monitor\IISLogMonitor.ps1"_. Then I can get the service args with the code `string[] serviceImagePathArgs = Environment.GetCommandLineArgs();`. What are you trying to do? – Rosberg Linhares Nov 09 '16 at 20:24
  • Yes you are correct. I got empty args because when I modified the registry value I uninstalled service and installed it again, so it reset the key value. –  Nov 10 '16 at 03:18
1

Arguments passed on the command-line via ImagePath are accessible in main() or via GetCommandLine(). You could install with command-line args and then in your ServiceMain, check to see if any arguments were passed in the lpszArgs parameter. If not, call GetCommandLine and see if any were passed that way.

Dustin
  • 388
  • 1
  • 9
  • Testing at both Exe and service level would be a solution for a single service Exe. But it would require to rewrite the service and would not work also with multiple services in the same Exe. – Francesca Sep 28 '09 at 22:34
  • I think that Remus' answer about using the Parameters registry key is your only option here. I don't think that there is any way to get service parameters passed for auto start services. – Dustin Sep 29 '09 at 18:57
1

Powershell can do this but you have to use .Net to achieve it.

new-Object System.ServiceProcess.ServiceController("$ServiceName",$ComputerName)).Start("$Parameter")
rene
  • 41,474
  • 78
  • 114
  • 152
virgored
  • 11
  • 1
1

The only thing that worked for me was to add the parameter to the ImagePath on the registry like the following image : enter image description here

gatsby
  • 1,148
  • 11
  • 12
0

If there is more than one service with the same executable then you would be installing them with different service names. You could refer to the service name instead of the parameters.

To get the service name you can use this How can a Windows Service determine its ServiceName?

Community
  • 1
  • 1
timothy
  • 568
  • 8
  • 9
0

A good illustration is to look how Mysql is working:

>sc qc MySql80
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: MySql80
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 8.0\my.ini" MySQL80
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : MySQL80
        DEPENDENCIES       :

you can then install or update your service:

sc config XXXXService binPath="\"C:\License Manager\Bin\LicenseService.exe\" 9002"

Note the escaped quotes to protect the .exe from any Path hijacking. also on your implementation, the value passed this way is not propagated to the OnStart(string[] args);

Your target service must add dedicated code to obtain value of command line. in the same context of tricky things on windows service : beware that current directory is System32, that you can bypass by using finding the base directory of the current ApplicationDomain, or even passing the desired directory also on command line at the installation stage.

Thierry Brémard
  • 625
  • 1
  • 5
  • 14
-1

Use the SC (service control) command, it gives you a lot more options than just start & stop.

DESCRIPTION:
          SC is a command line program used for communicating with the
          NT Service Controller and services.
  USAGE:
      sc <server> [command] [service name]  ...

      The option <server> has the form "\\ServerName"
      Further, help on commands can be obtained by typing: "sc [command]"
      Commands:
        query-----------Queries the status for a service, or
                        enumerates the status for types of services.
        queryex---------Queries the extended status for a service, or
                        enumerates the status for types of services.
        start-----------Starts a service.
        pause-----------Sends a PAUSE control request to a service.
        interrogate-----Sends an INTERROGATE control request to a service.
        continue--------Sends a CONTINUE control request to a service.
        stop------------Sends a STOP request to a service.
        config----------Changes the configuration of a service (persistent).
        description-----Changes the description of a service.
        failure---------Changes the actions taken by a service upon failure.
        qc--------------Queries the configuration information for a service.
        qdescription----Queries the description for a service.
        qfailure--------Queries the actions taken by a service upon failure.
        delete----------Deletes a service (from the registry).
        create----------Creates a service. (adds it to the registry).
        control---------Sends a control to a service.
        sdshow----------Displays a service's security descriptor.
        sdset-----------Sets a service's security descriptor.
        GetDisplayName--Gets the DisplayName for a service.
        GetKeyName------Gets the ServiceKeyName for a service.
        EnumDepend------Enumerates Service Dependencies.

      The following commands don't require a service name:
      sc <server> <command> <option>
        boot------------(ok | bad) Indicates whether the last boot should
                        be saved as the last-known-good boot configuration
        Lock------------Locks the Service Database
        QueryLock-------Queries the LockStatus for the SCManager Database
  EXAMPLE:
          sc start MyService
Tejas Bagade
  • 163
  • 1
  • 4