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.
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.
How about putting the parameter in a config file?
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();.
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.
Powershell can do this but you have to use .Net to achieve it.
new-Object System.ServiceProcess.ServiceController("$ServiceName",$ComputerName)).Start("$Parameter")
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?
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
The only thing that worked for me was to add the parameter to the ImagePath on the registry like the following image :