Podczas tworzenia usługi za pomocą programu sc.exe, jak przekazać parametry kontekstu?


143

Podczas tworzenia usługi Windows przy użyciu:

sc create ServiceName binPath= "the path"

w jaki sposób argumenty mogą być przekazywane do kolekcji Context.Parameters klasy Installer?

Czytam sc.exedokumentację, że takie argumenty można było przekazać dopiero na końcu binPath, ale nie znalazłem przykładu ani nie udało mi się to z powodzeniem zrobić.


Rzut oka na klucz Services w Rejestrze sugeruje, że wszelkie potrzebne parametry są zawarte w wartości ImagePath, więc binPath= "c:\abc\def.exe /Param1=ghi"wydaje się, że to dobry pomysł. Czy odwrotne ukośniki muszą być znakami ucieczki (np. „C: \\ abc \\ ...”)? Co najgorsze, możesz później bezpośrednio edytować wartość rejestru, jeśli SC.EXE nie może tego zrobić.
ewall

1
Zrezygnowałem z sc.exe i używam installutil.exe w ten sposób: Installutil.exe / ServiceName = ”TheName” / targetdir = ”C: \ TheInstallDirectory \” / PackageRoot = ”PackageRootPath”
sympatric greg

Użyłem Installutil.exe, a dla starszej technologii używam Instsrv.exe z zestawu zasobów systemu Windows XP / 2003.
Gary Kindel,

Odpowiedzi:


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

Sztuczka polega na pozostawieniu spacji po znaku = w instrukcji create, a także na użyciu „” dla wszystkiego, co zawiera znaki specjalne lub spacje.

Wskazane jest określenie nazwy wyświetlanej usługi, a także ustawienie ustawienia początkowego na automatyczny, aby uruchamiał się automatycznie. Możesz to zrobić, określając DisplayName= yourdisplaynamei start= autow instrukcji tworzenia.

Oto przykład:

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

Jeśli to zadziałało, powinieneś zobaczyć:

[SC] CreateService SUCCESS

AKTUALIZACJA 1

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


39
Pamiętaj, że spacja po binPath = ( binPath= "C:\...") musi być obecna, inaczej to nie zadziała.
Onion-Knight

1
start= autojest ważna, więc po ponownym uruchomieniu usługa zostanie automatycznie uruchomiona. Bardzo dobrze, jeśli użytkownik końcowy nie jest ekspertem
LaBracca

21
Także jeśli trzeba przekazać dodatkowe parametry w binPathktóre wymagają cytaty muszą być chronione ( \") Przykład: Jeśli ścieżka była c:\some long path\some.exe "first argument"musiałaby byćbinPath= "\"c:\some long path\some.exe\" \"first argument\""
Lankymart

1
Jeśli nie masz spacji po „=” w swoich argumentach (jak binPath= ...i DisplayName= ...; w moim przypadku zapomniałem „=” po DisplayName), konsola wydrukuje instrukcje użycia createpolecenia; jak: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....etc
The Red Pea

3
Spacje po „=” są bardzo ważne
ErisoHV

152

Parametry dla tworzonych usług mają specyficzne problemy z formatowaniem, w szczególności jeśli polecenie zawiera spacje lub cudzysłowy:

Jeśli chcesz wprowadzić parametry wiersza poleceń dla usługi, musisz ująć cały wiersz poleceń w cudzysłów. (I zawsze zostawiaj spację po binPath=i przed pierwszym cudzysłowem, jak zauważyła pani mrswadge)

Tak więc, aby utworzyć usługę dla polecenia PATH\COMMAND.EXE --param1=xyz , należy użyć następującego parametru binPath:

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

Jeśli ścieżka do pliku wykonywalnego zawiera spacje , trzeba ująć ścieżkę w cudzysłów.

Więc dla polecenia, które ma oba parametry i ścieżkę ze spacjami, potrzebujesz zagnieżdżonych cudzysłowów . Musisz uciec od wewnętrznych cudzysłowów za pomocą odwrotnych ukośników \". To samo dotyczy sytuacji, gdy parametry same w sobie zawierają cudzysłowy, musisz je również uciec.

Pomimo używania ukośników odwrotnych jako znaków ucieczki, nie musisz uciekać przed zwykłymi ukośnikami odwrotnymi zawartymi na ścieżce. Jest to sprzeczne z tym, jak zwykle używasz odwrotnych ukośników jako znaków ucieczki.

Więc dla polecenia takiego jak
"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

Oto konkretny przykład z dokumentacji SVNserve, który pokazuje wszystkie specjalne przypadki:

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

(dla czytelności dodawane są podziały wierszy, nie uwzględniaj ich)

To dodałoby nową usługę z linią poleceń "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

Podsumowując

  • miejsce po każdego parametru SC: binpath=_, displayname=_idepend=_
  • każdy parametr sc zawierający spacje musi być ujęty w cudzysłów
  • wszystkie dodatkowe cudzysłowy wewnątrz binpath są poprzedzone odwrotnym ukośnikiem: \"
  • wszystkie ukośniki odwrotne wewnątrz binpath nie są chronione

7
Zauważyłem, że ważne jest, aby zapewnić spację między binPath = a wartością „myservice.exe”. tj binPath= "myservice.exe. Interpreter wiersza poleceń musi się tego spodziewać i wymagać, aby polecenie stało się tokenizowane przy użyciu spacji jako separatora.
mrswadge

Próbowałem w ten sposób i zadziałało. SC.EXE "\\ ServerName" Create "ServiceName" BinPath = "SampleService.exe"
Sai


5

Miałem problemy z uruchomieniem tego w systemie Windows 7. Wydawało się, że zignorowano pierwszy argument, który podałem, więc użyłem binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"i zadziałało.


4

Po prostu tworzę go bez parametrów, a następnie edytuję rejestr HKLM\System\CurrentControlSet\Services\[YourService].


2

To polecenie działa:

sc create startSvn binPath= "\"C:\Subversion\bin\svnserve.exe\" --service -r \"C:\SVN_Repository\"" displayname= "MyServer" depend= tcpip start= auto

2

Należy również wziąć pod uwagę sposób uzyskiwania dostępu do argumentów w kodzie aplikacji.

W mojej aplikacji C # użyłem klasy ServiceBase:

 class MyService : ServiceBase
{

    protected override void OnStart(string[] args)
    {
       }
 }

Zarejestrowałem usługę za pomocą

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

Ale nie mogłem uzyskać dostępu do argumentów za pośrednictwem argszmiennej, gdy uruchamiam ją jako usługę.

Dokumentacja MSDN sugeruje, aby nie używać metody Main do pobierania argumentów binPathlub ImagePath. Zamiast tego sugeruje umieszczenie logiki w OnStartmetodzie, a następnie użycie (C #) Environment.GetCommandLineArgs();.

Aby uzyskać dostęp do pierwszych argumentów arg1, muszę zrobić w ten sposób:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

                log.Info("arg1 == "+Environment.GetCommandLineArgs()[1]);

       }
 }

to by się wydrukowało

       arg1 == arg1

Możesz również pobrać swoje arg1 i arg2 z parametru args w metodzie Main.
Wojciech Mikołajewicz

1

Znalazłem sposób na użycie sc.

sc config binPath = "\" c: \ ścieżka ze spacjami \ service_executable.exe \ ""

Innymi słowy, użyj \, aby uciec przed wszystkimi znakami ", które chcesz przetrwać przejście do rejestru.


1

Przykład tworzenia usługi z użyciem odwrotnych ukośników z wieloma podwójnymi cudzysłowami.

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

0

Upewnij się, że na początku i na końcu wartości binPath znajdują się cudzysłowy.


1
Mając ścieżkę „c: \ abc \ def.exe”, próbowałem przekazać parametr Param1 = „ghi” w następujący sposób: binPath = „c: \ abc \ def.exe / Param1 = ghi”. Ale bez pracy ...
sympatric greg

0

Nie mogłem poradzić sobie z problemem z twoimi propozycjami, na końcu z folderem x86 działał tylko w Power Shell (Windows Server 2012) przy użyciu zmiennych środowiskowych:

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

0

Jeśli wypróbowałeś wszystkie powyższe i nadal nie możesz przekazać argumentów do swojej usługi, jeśli twoja usługa została napisana w C / C ++, oto, co może być problemem: kiedy uruchamiasz usługę przez "sc start arg1 arg2 ..." , SC wywołuje funkcję ServiceMain usługi bezpośrednio z tymi argumentami. Ale kiedy system Windows uruchamia usługę (na przykład podczas rozruchu), wywoływana jest główna funkcja usługi (_tmain) z parametrami z „binPath” rejestru.


0

nie działa w Powershell i powinien używać CMD w moim przypadku


naprawiono w PowerShell 5.1
oetzi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.