web-dev-qa-db-fra.com

Lors de la création d'un service avec sc.exe, comment passer en paramètres de contexte?

Lors de la création d'un service Windows à l'aide de:

sc create ServiceName binPath= "the path"

comment les arguments peuvent-ils être passés à la collection Context.Parameters de la classe Installer?

D'après ma lecture de la documentation sc.exe, ces arguments ne peuvent être transmis qu'à la fin de binPath, mais je n'ai pas trouvé d'exemple ni réussi à le faire.

136
sympatric greg
sc create <servicename> binpath= "<pathtobinaryexecutable>" [option1] [option2] [optionN]

L'astuce consiste à laisser un espace après le = dans votre instruction de création et à utiliser "" pour tout élément contenant des caractères spéciaux ou des espaces.

Il est conseillé de spécifier un nom d'affichage pour le service et de définir le paramètre de démarrage sur auto afin qu'il démarre automatiquement. Vous pouvez le faire en spécifiant DisplayName= yourdisplayname et start= auto dans votre instruction create.

Voici un exemple:

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

Si cela fonctionnait, vous devriez voir:

[SC] CreateService SUCCESS

UPDATE 1

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

240
Mhmd

Les paramètres des services créés posent des problèmes de mise en forme particuliers, en particulier si la commande comprend des espaces ou des guillemets:

Si vous voulez entrer paramètres de ligne de commande pour le service, vous devez inclure la ligne de commande complète entre guillemets. (Et laissez toujours un espace après binPath= et avant la première citation, comme l'a souligné mrswadge)

Ainsi, pour créer un service pour la commande PATH\COMMAND.EXE --param1=xyz, vous utiliseriez le paramètre binPath suivant:

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

Si le chemin de l'exécutable contient des espaces, vous devez mettre le chemin entre guillemets.

Donc, pour une commande qui a à la fois paramètres et un chemin avec des espaces, vous avez besoin de guillemets imbriqués. Vous devez échapper aux guillemets intérieurs avec des barres obliques inverses \". Il en va de même si les paramètres contiennent des guillemets, vous devrez également y échapper.

Bien que vous utilisiez des barres obliques inverses comme caractères d'échappement, vous n'êtes pas obligé d'échapper aux barres obliques inverses contenues dans le chemin. Ceci est contraire à la façon dont vous utilisez normalement des barres obliques inverses comme caractères d'échappement.

Donc, pour une commande comme
"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

Voici un exemple concret de la documentation SVNserve, qui montre tous les cas particuliers:

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

(les sauts de ligne sont ajoutés pour la lisibilité, ne les incluez pas)

Cela ajouterait un nouveau service avec la ligne de commande "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

donc en résumé

  • espace après chaque paramètre sc: binpath=_, displayname=_ et depend=_
  • chaque paramètre sc contenant des espaces doit être placé entre guillemets
  • toutes les citations supplémentaires à l'intérieur du chemin bin sont masquées avec des barres obliques inverses: \"
  • toutes les barres obliques inverses à l'intérieur du chemin bin ne sont pas échappées
137
HugoRune
 sc crée "YOURSERVICENAME" binpath = "\" C:\Fichiers de programme (x86)\Microsoft SQL Server\MSSQL11\MSSQL\Binn\sqlservr.exe\"-sOPTIONALSWITCH" start = auto 

Voir ici: Modification du "Chemin d'accès à l'exécutable" d'un service Windows

11
imjustarah

J'ai eu des problèmes pour que cela fonctionne sous Windows 7. Il semblait ignorer le premier argument que je passais donc j'ai utilisé binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2" et cela a fonctionné.

5
Craig Carpenter

J'utilise simplement le créer sans paramètres, puis édite le registre HKLM\System\CurrentControlSet\Services\[YourService].

4
Tony

Cette commande fonctionne:

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

Il est également important de prendre en compte la manière dont vous accédez aux arguments dans le code de l'application.

Dans mon application c #, j'ai utilisé la classe ServiceBase:

 class MyService : ServiceBase
{

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

J'ai enregistré mon service en utilisant

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

Mais je ne pouvais pas accéder aux arguments via la variable args lorsque je l'exécutais en tant que service.

La documentation MSDN suggère de ne pas utiliser la méthode Main pour extraire les arguments binPath ou ImagePath. Au lieu de cela, il suggère de placer votre logique dans la méthode OnStart, puis d’utiliser (C #) Environment.GetCommandLineArgs();.

Pour accéder aux premiers arguments arg1, je dois procéder comme suit:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

cela imprimerait

       arg1 == arg1
2
Panciz

J'ai trouvé un moyen d'utiliser sc.

sc config binPath = "\" c:\chemin contenant des espaces\service_executable.exe\""

En d'autres termes, utilisez\pour échapper à tout "s" vous voulez survivre au transit dans le registre.

1
Rem Onyshczak

Je ne pouvais pas gérer le problème avec vos propositions. À la fin, le dossier x86 ne fonctionnait que dans Power Shell (Windows Server 2012) à l'aide de variables d'environnement:

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

Si vous avez essayé tout ce qui précède et que vous ne pouvez toujours pas transmettre les arguments à votre service, si votre service a été écrit en C/C++, voici le problème: lorsque vous démarrez votre service via "sc start arg1 arg2 ..." , SC appelle la fonction ServiceMain de votre service directement avec ces arguments. Mais lorsque Windows démarre votre service (au démarrage, par exemple), c'est la fonction principale de votre service (_tmain) qui est appelée, avec les paramètres du "binPath" du registre.

0
BlueRiver

Exemple de création de service utilisant des barres obliques inverses avec de nombreux guillemets.

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
Nash A

Assurez-vous d'avoir des guillemets au début et à la fin de votre valeur binPath.

0
cripox