Wie werden beim Erstellen eines Dienstes mit sc.exe Kontextparameter übergeben?

143

Beim Erstellen eines Windows-Dienstes mit:

sc create ServiceName binPath= "the path"

Wie können Argumente an die Context.Parameters-Auflistung der Installer-Klasse übergeben werden?

Ich habe die sc.exeDokumentation gelesen und binPathfestgestellt, dass solche Argumente erst am Ende von übergeben werden konnten , aber ich habe kein Beispiel gefunden oder konnte dies erfolgreich tun.

sympatric greg
quelle
Ein Blick auf den Diensteschlüssel in der Registrierung legt nahe, dass alle erforderlichen Parameter im ImagePath-Wert enthalten sind. Sie binPath= "c:\abc\def.exe /Param1=ghi"scheinen also die richtige Idee zu sein. Müssen die Backslashes maskiert werden (dh "c: \\ abc \\ ...")? Das Schlimmste ist, dass Sie den Registrierungswert anschließend direkt bearbeiten können, wenn SC.EXE dies nicht kann.
Ewall
1
Ich habe sc.exe aufgegeben und verwende installutil.exe wie folgt: Installutil.exe / ServiceName = ”TheName” / targetdir = ”C: \ TheInstallDirectory \” / PackageRoot = ”PackageRootPath”
sympatric greg
Ich habe Installutil.exe verwendet und für ältere Technologien verwende ich Instsrv.exe von Windows XP / 2003 Resource Ket.
Gary Kindel

Antworten:

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

Der Trick besteht darin, ein Leerzeichen nach dem = in Ihrer create-Anweisung zu lassen und "" für alles zu verwenden, das Sonderzeichen oder Leerzeichen enthält.

Es ist ratsam, einen Anzeigenamen für den Dienst anzugeben und die Starteinstellung auf automatisch zu setzen, damit er automatisch gestartet wird. Sie können dies tun, indem Sie DisplayName= yourdisplaynameund start= autoin Ihrer create-Anweisung angeben.

Hier ist ein Beispiel:

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

Wenn dies funktioniert hat, sollten Sie sehen:

[SC] CreateService SUCCESS

UPDATE 1

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

Mhmd
quelle
39
Beachten Sie, dass der Speicherplatz nach binPath = ( binPath= "C:\...") vorhanden sein muss , da dies sonst nicht funktioniert.
Zwiebel-Ritter
1
start= autoist wichtig, daher wird der Dienst nach dem Neustart automatisch gestartet. Sehr gut für den Fall, dass der Endbenutzer kein Experte ist
LaBracca
21
Auch wenn Sie zusätzliche Parameter in den binPathAnführungszeichen übergeben müssen, müssen diese \"c:\some long path\some.exe "first argument"binPath= "\"c:\some long path\some.exe\" \"first argument\""
maskiert
1
Wenn Sie in Ihren Argumenten kein Leerzeichen nach dem "=" haben (wie binPath= ...und DisplayName= ...; in meinem Fall habe ich das "=" nach DisplayName vergessen), druckt die Konsole die Verwendungsanweisungen für den createBefehl. wie: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....etc
Die rote Erbse
3
Die Leerzeichen nach dem "=" sind sehr wichtig
ErisoHV
152

Parameter für erstellte Dienste weisen einige besondere Formatierungsprobleme auf, insbesondere wenn der Befehl Leerzeichen oder Anführungszeichen enthält:

Wenn Sie Befehlszeilenparameter für den Dienst eingeben möchten , müssen Sie die gesamte Befehlszeile in Anführungszeichen setzen. (Und lassen Sie nach binPath=und vor dem ersten Zitat immer ein Leerzeichen , wie Frau Wadge betonte)

PATH\COMMAND.EXE --param1=xyz Um einen Dienst für den Befehl zu erstellen, verwenden Sie den folgenden binPath-Parameter:

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

Wenn der Pfad zur ausführbaren Datei Leerzeichen enthält , müssen Sie den Pfad in Anführungszeichen setzen.

Für einen Befehl, der sowohl Parameter als auch einen Pfad mit Leerzeichen enthält, benötigen Sie verschachtelte Anführungszeichen . Sie müssen den inneren Anführungszeichen mit Backslashes entkommen\" . Das Gleiche gilt, wenn die Parameter selbst Anführungszeichen enthalten, müssen Sie diese ebenfalls umgehen.

Obwohl Sie Backslashes als Escape-Zeichen verwenden, müssen Sie sich nicht den regulären Backslashes im Pfad entziehen. Dies steht im Widerspruch dazu, wie Sie normalerweise Backslashes als Escape-Zeichen verwenden.

Also für einen Befehl wie
"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

Hier ist ein konkretes Beispiel aus der SVNserve-Dokumentation, die alle Sonderfälle zeigt:

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

(Zeilenumbrüche werden zur besseren Lesbarkeit hinzugefügt, schließen Sie sie nicht ein.)

Dies würde einen neuen Dienst mit der Befehlszeile hinzufügen "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

Also zusammenfassend

  • Leerzeichen nach jedem sc-Parameter : binpath=_,displayname=_ unddepend=_
  • Jeder sc-Parameter, der Leerzeichen enthält, muss in Anführungszeichen gesetzt werden
  • Alle zusätzlichen Anführungszeichen im Binpath werden mit Backslashes maskiert: \"
  • Alle Backslashes im Binpath werden nicht maskiert
HugoRune
quelle
7
Ich fand es wichtig sicherzustellen, dass zwischen binPath = und dem Wert "myservice.exe" ein Leerzeichen steht. dh binPath= "myservice.exe. Der Befehlszeileninterpreter muss dies erwarten und verlangen, dass der Befehl durch Verwendung von Leerzeichen als Trennzeichen tokenisiert wird.
Frau Wadge
Ich habe es so versucht und es hat funktioniert. SC.EXE "\\ Servername" Erstellen Sie "ServiceName" BinPath = "SampleService.exe"
Sai
5

Ich hatte Probleme damit, dass dies unter Windows 7 funktioniert. Es schien das erste Argument zu ignorieren, das ich eingegeben habe, also habe ich es verwendet binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"und es hat funktioniert.

Craig Carpenter
quelle
4

Ich erstelle es einfach ohne Parameter und bearbeite dann die Registrierung HKLM\System\CurrentControlSet\Services\[YourService].

Tony
quelle
2

Dieser Befehl funktioniert:

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

Es ist auch wichtig zu berücksichtigen, wie Sie auf die Argumente im Code der Anwendung zugreifen.

In meiner c # -Anwendung habe ich die ServiceBase-Klasse verwendet:

 class MyService : ServiceBase
{

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

Ich habe meinen Dienst mit registriert

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

Ich konnte jedoch nicht über die argsVariable auf die Argumente zugreifen , wenn ich sie als Dienst ausführte.

Die MSDN - Dokumentation schlägt vor , mit der Main - Methode nicht abrufen binPathoder ImagePathArgumente. Stattdessen wird vorgeschlagen, Ihre Logik in die OnStartMethode einzufügen und dann (C #) zu verwenden Environment.GetCommandLineArgs();.

Um auf die ersten Argumente zuzugreifen, muss arg1ich Folgendes tun:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

das würde drucken

       arg1 == arg1
Panciz
quelle
Sie können Ihre Argumente arg1 und arg2 auch über den Parameter args in der Main-Methode abrufen.
Wojciech Mikołajewicz
1

Ich habe einen Weg gefunden, sc zu benutzen.

sc config binPath = "" c: \ Pfad mit Leerzeichen \ service_executable.exe "

Mit anderen Worten, verwenden Sie \, um alle "'s zu umgehen, die Sie den Transit in die Registrierung überleben möchten.

Rem Onyshczak
quelle
1

Ein Beispiel für die Erstellung von Diensten zur Verwendung von Backslashes mit vielen doppelten Anführungszeichen.

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
Nash A.
quelle
0

Stellen Sie sicher, dass am Anfang und am Ende Ihres binPath-Werts Anführungszeichen stehen.

Cripox
quelle
1
Bei einem Pfad "c: \ abc \ def.exe" habe ich versucht, Param1 = "ghi" wie folgt zu übergeben: binPath = "c: \ abc \ def.exe / Param1 = ghi". Aber keine Arbeit ...
Sympatric
0

Ich konnte das Problem mit Ihren Vorschlägen nicht lösen. Am Ende funktionierte der x86-Ordner nur in der Power Shell (Windows Server 2012) mithilfe von Umgebungsvariablen:

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

Wenn Sie alle oben genannten Versuche unternommen haben und weiterhin keine Argumente an Ihren Dienst übergeben können und Ihr Dienst in C / C ++ geschrieben wurde, kann dies das folgende Problem sein: Wenn Sie Ihren Dienst über "sc start arg1 arg2 ..." starten , SC ruft die ServiceMain-Funktion Ihres Dienstes direkt mit diesen Argumenten auf. Wenn Windows Ihren Dienst startet (z. B. beim Booten), wird die Hauptfunktion Ihres Dienstes (_tmain) mit Parametern aus dem "binPath" der Registrierung aufgerufen.

BlueRiver
quelle
0

Es funktioniert nicht in der Powershell und sollte in meinem Fall CMD verwenden

Wilhelm
quelle
behoben in PowerShell 5.1
oetzi