181

When creating Windows service using:

sc create ServiceName binPath= "the path"

how can arguments be passed to the Installer class's Context.Parameters collection?

My reading of the sc.exe documentation is that such arguments could only be passed on the end of binPath, but I have not found an example or been able to successfully do this.

andrews
  • 2,173
  • 2
  • 16
  • 29
sympatric greg
  • 2,969
  • 2
  • 24
  • 29
  • A glance at the Services key in the Registry suggests that any needed parameters are included with the ImagePath value, so your `binPath= "c:\abc\def.exe /Param1=ghi"` seems like the right idea. Do the backslashes need to be escaped (i.e. "c:\\abc\\...")? Worst thing, you could directly edit the Registry value afterwards if SC.EXE can't do it. – ewall Sep 08 '10 at 14:37
  • 1
    I gave up on sc.exe and am using installutil.exe like so: Installutil.exe /ServiceName=”TheName” /targetdir=”C:\TheInstallDirectory\” /PackageRoot=”PackageRootPath” – sympatric greg Sep 08 '10 at 16:45
  • I used Installutil.exe and for older technology I use Instsrv.exe from Windows XP/2003 Resource Ket. – Gary Kindel Feb 25 '11 at 18:58

14 Answers14

293
sc create <servicename> binpath= "<pathtobinaryexecutable>" [option1] [option2] [optionN]

The trick is to leave a space after the = in your create statement, and also to use " " for anything containing special characters or spaces.

It is advisable to specify a Display Name for the service as well as setting the start setting to auto so that it starts automatically. You can do this by specifying DisplayName= yourdisplayname and start= auto in your create statement.

Here is an example:

C:\Documents and Settings\Administrator> sc create asperacentral 
binPath= "C:\Program Files\Aspera\Enterprise Server\bin\Debug\asperacentral.exe" 
DisplayName= "Aspera Central" 
start= auto

If this worked you should see:

[SC] CreateService SUCCESS

UPDATE 1

http://support.microsoft.com/kb/251192

roapp
  • 530
  • 6
  • 17
Mhmd
  • 4,989
  • 3
  • 22
  • 29
  • 43
    Keep in mind that the space after binPath= (`binPath= "C:\..."`) *needs* to be present, or else this won't work. – Onion-Knight Apr 22 '13 at 14:48
  • @Onion-Knight The space was exactly what I was missing. Thanks a lot – Michel Jun 14 '13 at 13:21
  • 2
    `start= auto` is an important one, so after reboot the service will be automatically started. Very good in case the end user is not an expert – UnDiUdin Jan 29 '14 at 12:54
  • 29
    Also if you need to pass extra parameters in the `binPath` that require quotes they have to be escaped (`\"`) example: if the path was `c:\some long path\some.exe "first argument"` it would need to be `binPath= "\"c:\some long path\some.exe\" \"first argument\""` – user692942 Jul 16 '15 at 13:38
  • 2
    If you don't have a space after the "=" in your args (like `binPath= ...` and `DisplayName= ...`; in my case I forgot the "=" after DisplayName), then the console will print the usage instructions for the `create` command; like: `DESCRIPTION: Creates a service entry... USAGE: sc create....` etc – Nate Anderson Feb 28 '16 at 18:02
  • And in my case I needed to open the console in admin mode, or else I got "Access denied" – Nate Anderson Feb 28 '16 at 18:03
  • 3
    The spaces after the "=" is very important – ErisoHV Apr 06 '18 at 16:19
  • 1
    @Lankymart Great answer. The most tricky part is to use the "\" as the escape symbol. – Neveroldmilk Jan 31 '19 at 00:41
  • worth noting that this command is only available for windows server ( and some older windows versions ). Win 10 has an `sc` command also but it's something different, can't be used to register services. – Captain Dashenka Oct 07 '19 at 13:04
210

Parameters for created services have some peculiar formating issues, in particular if the command includes spaces or quotes:

If you want to enter command line parameters for the service, you have to enclose the whole command line in quotes. (And always leave a space after binPath= and before the first quote, as mrswadge pointed out)

So, to create a service for the command PATH\COMMAND.EXE --param1=xyz you would use the following binPath parameter:

binPath= "PATH\COMMAND.EXE --param1=xyz"
        ^^                             ^
        ||                             |
  space    quote                     quote

If the path to the executable contains spaces, you have to enclose the path in quotes.

So for a command that has both parameters and a path with spaces, you need nested quotes. You have to escape the inner quotes with backslashes \". The same holds if the parameters themselves contain quotes, you will need to escape those too.

Despite using backslashes as escape characters, you do not have to escape the regular backslashes contained in the path. This is contrary to how you normally use backslashes as escape characters.

So for a command like
"PATH WITH SPACES \COMMAND.EXE" --param-with-quotes="a b c" --param2:

binPath= "\"PATH WITH SPACES \COMMAND.EXE\" --param-with-quotes=\"a b c\" --param2"
         ^ ^                 ^           ^                      ^       ^         ^
         | |                 |           |                      |       |         | 
 opening     escaped      regular     escaped                    escaped       closing
   quote     quote       backslash    closing                    quotes          quote
     for     for            in         quote                      for              for
   whole     path          path       for path                  parameter        whole
 command                                                                       command

Here is a concrete example from the SVNserve documentation, which shows all special cases:

sc create svnserve 
   binpath= "\"C:\Program Files\CollabNet Subversion Server\svnserve.exe\" --service -r \"C:\my repositories\"  "
   displayname= "Subversion Server" depend= Tcpip start= auto 

(linebreaks are added for readability, do not include them)

This would add a new service with the command line "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

So in summary

  • space after each sc parameter: binpath=_, displayname=_ and depend=_
  • each sc parameter that contains spaces must be enclosed in quotes
  • all additional quotes inside the binpath are escaped with backslashes: \"
  • all backslashes inside the binpath are not escaped
HugoRune
  • 13,157
  • 7
  • 69
  • 144
  • 9
    I found it was important to ensure there is a space between binPath= and the value "myservice.exe". i.e. `binPath= "myservice.exe`. The command line interpreter must be expecting this and requiring the command to become tokenized by using space as the delimiter. – mrswadge Mar 20 '13 at 09:24
  • I tried this way and it worked. SC.EXE "\\ServerName" Create "ServiceName" BinPath="SampleService.exe" – Sai May 05 '15 at 07:56
  • 1
    This should be in the MS docs on `sc.exe create` – Joseph Aug 27 '21 at 20:02
  • 2
    Is this spacing still relevant? It works without it now. I'm using windows 10. – Larry Jun 30 '22 at 18:47
14
sc create "YOURSERVICENAME" binpath= "\"C:\Program Files (x86)\Microsoft SQL Server\MSSQL11\MSSQL\Binn\sqlservr.exe\" -sOPTIONALSWITCH" start= auto 

See here: Modifying the "Path to executable" of a windows service

roapp
  • 530
  • 6
  • 17
imjustarah
  • 161
  • 1
  • 6
6

I had issues getting this to work on Windows 7. It seemed to ignore the first argument I passed in so I used binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2" and it worked.

sra
  • 23,820
  • 7
  • 55
  • 89
4

I use to just create it without parameters, and then edit the registry HKLM\System\CurrentControlSet\Services\[YourService].

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Tony
  • 49
  • 1
  • 1
4

It also important taking in account how you access the Arguments in the code of the application.

In my c# application I used the ServiceBase class:

class MyService : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        //
    }
}

I registered my service using

sc create myService binpath= "MeyService.exe arg1 arg2"

But I couldn't access the arguments through the args variable when I run it as a service.

The MSDN documentation suggests not using the Main method to retrieve the binPath or ImagePath arguments. Instead it suggests placing your logic in the OnStart method and then using (C#) Environment.GetCommandLineArgs();.

To access the first arguments arg1 I need to do like this:

class MyService : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        log.Info("arg1 == "+Environment.GetCommandLineArgs()[1]);
    }
}

this would print

arg1 == arg1
roapp
  • 530
  • 6
  • 17
Panciz
  • 2,183
  • 2
  • 30
  • 54
4

A service creation example of using backslashes with many double quotes.

C:\Windows\system32>sc.exe create teagent binpath= "\"C:\Program Files\Tripwire\TE\Agent\bin\wrapper.exe\" -s \"C:\Program Files\Tripwire\TE\Agent\bin\agent.conf\"" DisplayName= "Tripwire Enterprise Agent"

[SC] CreateService SUCCESS
roapp
  • 530
  • 6
  • 17
Nash A
  • 87
  • 6
3

This command works:

sc create startSvn binPath= "\"C:\Subversion\bin\svnserve.exe\" --service -r \"C:\SVN_Repository\"" displayname= "MyServer" depend= tcpip start= auto
roapp
  • 530
  • 6
  • 17
user2535091
  • 31
  • 1
  • 4
1

I found a way to use sc.

sc config binPath= "\"c:\path with spaces in it\service_executable.exe\" "

In other words, use \ to escape any "'s you want to survive the transit into the registry.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
0

I couldn't handle the issue with your proposals, at the end with the x86 folder it only worked in power shell (windows server 2012) using environment variables:

{sc.exe create svnserve binpath= "${env:programfiles(x86)}/subversion/bin/svnserve.exe --service -r C:/svnrepositories/"   displayname= "Subversion Server" depend= Tcpip start= auto}
roapp
  • 530
  • 6
  • 17
0

Be sure to have quotes at beginning and end of your binPath value.

sc create Stuff binPath= "C:\Windows\system32\stuff.exe" DisplayName= "Stuff Update Service" start= auto

sc description Stuff "service to update stuff"

sc query Stuff

sc qdescription Stuff

sc qc Stuff

sc start Stuff

cripox
  • 556
  • 1
  • 7
  • 19
  • 1
    Given a path "c:\abc\def.exe", I tried to pass in Param1="ghi" like this: binPath= "c:\abc\def.exe /Param1=ghi". But no worky... – sympatric greg Sep 08 '10 at 00:29
0

If you tried all of the above and still can't pass args to your service, if your service was written in C/C++, here's what could be the problem: when you start your service through "sc start arg1 arg2...", SC calls your service's ServiceMain function directly with those args. But when Windows start your service (at boot time, for example), it's your service's main function (_tmain) that's called, with params from the registry's "binPath".

BlueRiver
  • 3
  • 1
  • 4
0

it is not working in the Powershell and should use CMD in my case

William
  • 141
  • 5
0

In W2008 Server you still need the space, e.g. binPath= "", but in W2019 Server it is fixed, and binPath="" works

Coder Dev
  • 113
  • 2
  • 9