Quando si crea un servizio con sc.exe come passare i parametri di contesto?


143

Quando si crea il servizio Windows utilizzando:

sc create ServiceName binPath= "the path"

come possono essere passati argomenti alla raccolta Context.Parameters della classe Installer?

La mia lettura della sc.exedocumentazione è che tali argomenti potevano essere passati solo alla fine binPath, ma non ho trovato un esempio o non sono stato in grado di farlo con successo.


Un'occhiata alla chiave Servizi nel Registro di sistema suggerisce che tutti i parametri necessari sono inclusi con il valore ImagePath, quindi la tua binPath= "c:\abc\def.exe /Param1=ghi"sembra l'idea giusta. Le barre rovesciate devono essere sfuggite (ad es. "C: \\ abc \\ ...")? Peggio ancora, potresti modificare direttamente il valore del Registro di sistema in seguito se SC.EXE non può farlo.
ewall

1
Ho rinunciato a sc.exe e sto usando installutil.exe in questo modo: Installutil.exe / ServiceName = "TheName" / targetdir = "C: \ TheInstallDirectory \" / PackageRoot = "PackageRootPath"
greg

Ho usato Installutil.exe e per la tecnologia precedente utilizzo Instsrv.exe da Windows XP / 2003 Resource Ket.
Gary Kindel,

Risposte:


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

Il trucco è lasciare uno spazio dopo il = nella tua istruzione create e anche usare "" per qualsiasi cosa che contenga caratteri o spazi speciali.

È consigliabile specificare un nome visualizzato per il servizio e impostare l'impostazione di avvio su auto in modo che si avvii automaticamente. Puoi farlo specificando DisplayName= yourdisplaynamee start= autonella tua dichiarazione di creazione.

Ecco un esempio:

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

Se questo ha funzionato dovresti vedere:

[SC] CreateService SUCCESS

AGGIORNAMENTO 1

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


39
Tieni presente che lo spazio dopo binPath = ( binPath= "C:\...") deve essere presente, altrimenti non funzionerà.
Cavaliere della cipolla,

1
start= autoè importante, quindi dopo il riavvio il servizio verrà avviato automaticamente. Molto buono nel caso in cui l'utente finale non sia un esperto
LaBracca il

21
Inoltre, se è necessario passare parametri aggiuntivi nell'esempio binPathche richiede le virgolette, devono essere evitati ( \") esempio: se il percorso fosse c:\some long path\some.exe "first argument", dovrebbe esserebinPath= "\"c:\some long path\some.exe\" \"first argument\""
Lankymart

1
Se non hai uno spazio dopo "=" nel tuo args (come binPath= ...e DisplayName= ...; nel mio caso ho dimenticato "=" dopo DisplayName), allora la console stamperà le istruzioni d'uso per il createcomando; come: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....etc
The Red Pea,

3
Gli spazi dopo il "=" sono molto importanti
ErisoHV,

152

I parametri per i servizi creati presentano alcuni problemi di formattazione particolari, in particolare se il comando include spazi o virgolette:

Se si desidera immettere i parametri della riga di comando per il servizio, è necessario racchiudere l' intera riga di comando tra virgolette. (E lascia sempre uno spazio dopo binPath=e prima della prima citazione, come ha sottolineato mrswadge)

Quindi, per creare un servizio per il comando PATH\COMMAND.EXE --param1=xyz è necessario utilizzare il seguente parametro binPath:

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

Se il percorso del file eseguibile contiene spazi , è necessario racchiudere il percorso tra virgolette.

Quindi, per un comando che ha entrambi i parametri e un percorso con spazi, sono necessarie le virgolette nidificate . Devi sfuggire alle virgolette interne con barre rovesciate \". Lo stesso vale se i parametri stessi contengono virgolette, sarà necessario sfuggire anche a quelli.

Nonostante si utilizzino le barre rovesciate come caratteri di escape, non è necessario sfuggire alle barre rovesciate normali contenute nel percorso. Questo è in contrasto con il modo in cui normalmente usi le barre rovesciate come caratteri di escape.

Quindi per un comando come
"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

Ecco un esempio concreto dalla documentazione di SVNserve, che mostra tutti i casi speciali:

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

(le interruzioni di riga vengono aggiunte per la leggibilità, non includerle)

Ciò aggiungerebbe un nuovo servizio con la riga di comando "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

Quindi in sintesi

  • spazio dopo ogni parametro SC: binpath=_, displayname=_edepend=_
  • ogni parametro sc che contiene spazi deve essere racchiuso tra virgolette
  • tutte le virgolette aggiuntive all'interno del binpath sono salvate con barre rovesciate: \"
  • tutte le barre rovesciate all'interno del binpath non vengono salvate

7
Ho scoperto che era importante assicurarsi che ci fosse uno spazio tra binPath = e il valore "myservice.exe". vale a dire binPath= "myservice.exe. L'interprete della riga di comando deve aspettarsi questo e richiedere che il comando venga tokenizzato utilizzando lo spazio come delimitatore.
mrswadge,

Ho provato in questo modo e ha funzionato. SC.EXE "\\ ServerName" Crea "ServiceName" BinPath = "SampleService.exe"
Sai


5

Ho avuto problemi a farlo funzionare su Windows 7. Sembrava ignorare il primo argomento che ho passato, quindi l'ho usato binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"e ha funzionato.


4

Lo uso solo per crearlo senza parametri e quindi modificare il registro HKLM\System\CurrentControlSet\Services\[YourService].


2

Questo comando funziona:

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

2

È anche importante tenere conto del modo in cui accedi agli Argomenti nel codice dell'applicazione.

Nella mia applicazione c # ho usato la classe ServiceBase:

 class MyService : ServiceBase
{

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

Ho registrato il mio servizio utilizzando

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

Ma non sono riuscito ad accedere agli argomenti tramite la argsvariabile quando lo eseguo come servizio.

La documentazione MSDN suggerisce di non utilizzare il metodo Main per recuperare gli argomenti binPatho ImagePath. Invece suggerisce di inserire la logica nel OnStartmetodo e quindi di usare (C #) Environment.GetCommandLineArgs();.

Per accedere ai primi argomenti arg1devo fare così:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

questo verrebbe stampato

       arg1 == arg1

Puoi anche ottenere arg1 e arg2 dal parametro args sul metodo Main.
Wojciech Mikołajewicz,

1

Ho trovato un modo di usare sc.

sc config binPath = "\" c: \ path con spazi in esso \ service_executable.exe \ ""

In altre parole, usa \ per sfuggire a qualsiasi "s" che vuoi sopravvivere al transito nel registro.


1

Un esempio di creazione del servizio di utilizzo di barre rovesciate con molte virgolette doppie.

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

Assicurati di avere le virgolette all'inizio e alla fine del valore binPath.


1
Dato un percorso "c: \ abc \ def.exe", ho provato a passare Param1 = "ghi" in questo modo: binPath = "c: \ abc \ def.exe / Param1 = ghi". Ma niente da fare ...
greg

0

Non sono riuscito a gestire il problema con le tue proposte, alla fine con la cartella x86 ha funzionato solo in Power Shell (Windows Server 2012) usando le variabili di ambiente:

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

0

Se hai provato tutto quanto sopra e non riesci ancora a passare argomenti al tuo servizio, se il tuo servizio è stato scritto in C / C ++, ecco quale potrebbe essere il problema: quando avvii il servizio tramite "sc start arg1 arg2 ..." , SC chiama la funzione ServiceMain del servizio direttamente con questi argomenti. Ma quando Windows avvia il tuo servizio (all'avvio, ad esempio), viene chiamata la funzione principale del tuo servizio (_tmain), con parametri dal "binPath" del registro.


0

non funziona in Powershell e nel mio caso dovrebbe usare CMD


risolto in PowerShell 5.1
oetzi il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.