Dienst über Batch- oder Cmd-Datei stoppen und starten?

288

Wie kann ich ein Fledermaus- oder Cmd-Skript erstellen, um einen Dienst mit Fehlerprüfung zuverlässig zu stoppen und zu starten (oder mich wissen lassen, dass er aus irgendeinem Grund nicht erfolgreich war)?

Keng
quelle
Vielleicht etwas offtopisch (da Sie nach Anweisungen für bat & cmd fragen), aber: PowerShell bietet Ihnen viel Kontrolle und Feedback für solche Aktionen.
GvS

Antworten:

347

Verwenden Sie den SCBefehl (Service Control). Er bietet Ihnen viel mehr Optionen als nur start& stop.

  BESCHREIBUNG:
          SC ist ein Befehlszeilenprogramm für die Kommunikation mit dem
          NT Service Controller und Dienste.
  VERWENDUNG:
      sc <Server> [Befehl] [Dienstname] ...

      Die Option <Server> hat die Form "\\ Servername".
      Weitere Hilfe zu Befehlen erhalten Sie, indem Sie Folgendes eingeben: "sc [Befehl]"
      Befehle:
        Abfrage ----------- Fragt den Status eines Dienstes ab oder
                        Listet den Status für Diensttypen auf.
        queryex --------- Fragt den erweiterten Status für einen Dienst ab, oder
                        Listet den Status für Diensttypen auf.
        start ----------- Startet einen Dienst.
        pause ----------- Sendet eine PAUSE-Steuerungsanforderung an einen Dienst.
        Abfrage ----- Sendet eine INTERROGATE-Steuerungsanforderung an einen Dienst.
        weiter -------- Sendet eine CONTINUE-Steuerungsanforderung an einen Dienst.
        stop ------------ Sendet eine STOP-Anforderung an einen Dienst.
        config ---------- Ändert die Konfiguration eines Dienstes (persistent).
        description ----- Ändert die Beschreibung eines Dienstes.
        Fehler --------- Ändert die Aktionen, die ein Dienst bei einem Fehler ausführt.
        qc -------------- Fragt die Konfigurationsinformationen für einen Dienst ab.
        qdescription ---- Fragt die Beschreibung für einen Dienst ab.
        qfailure -------- Fragt die Aktionen ab, die ein Dienst bei einem Fehler ausführt.
        delete ---------- Löscht einen Dienst (aus der Registrierung).
        create ---------- Erstellt einen Service. (Fügt es der Registrierung hinzu).
        control --------- Sendet ein Steuerelement an einen Dienst.
        sdshow ---------- Zeigt die Sicherheitsbeschreibung eines Dienstes an.
        sdset ----------- Legt die Sicherheitsbeschreibung eines Dienstes fest.
        GetDisplayName - Ruft den DisplayName für einen Dienst ab.
        GetKeyName ------ Ruft den ServiceKeyName für einen Dienst ab.
        EnumDepend ------ Listet Dienstabhängigkeiten auf.

      Für die folgenden Befehle ist kein Dienstname erforderlich:
      sc <Server> <Befehl> <Option>
        boot ------------ (ok | bad) Gibt an, ob der letzte Start erfolgen soll
                        als die zuletzt bekannte gute Startkonfiguration gespeichert werden
        Sperren ------------ Sperrt die Servicedatenbank
        QueryLock ------- Fragt den LockStatus für die SCManager-Datenbank ab
  BEISPIEL:
          sc starte MyService
Ferruccio
quelle
1
Ich bin damit einverstanden, dass dies besser ist als Netto-Start / Stopp. Beachten Sie, dass es eine Option gibt, Dienste auch auf Remotecomputern zu berühren.
Outlaw Programmer
1
Gute Antwort. Sie müssen jedoch Administrator sein, um den SC-Startdienst ausführen zu können. Ich habe hier eine Lösung dafür gefunden . (Die akzeptierte Antwort enthält die Lösung)
Michael K.
56
Das Problem mit SC ist, dass der Befehl sofort und nicht nach Abschluss der Aktion zurückgegeben wird. Wenn Sie einen Dienst über eine Batchdatei neu starten möchten (Stopp, dann Start), kehrt der Stopp sofort zurück. Der Start schlägt dann fehl, weil der Dienst nicht gestoppt wird. Net Stop / Start kehrt nach Abschluss der Aktion zurück, hat also dieses Problem nicht.
Dom
Ich habe das cmd als Administratormodus geöffnet und einen Fehler erhalten. Die Syntax dieses Befehls lautet: NET STOP-Dienst
Satish Singh
Gibt es eine Möglichkeit zu überprüfen, ob der Dienst ordnungsgemäß gestoppt wurde? im Jahr 2020?
Anand Varkey Philips
212
net start [serviceName]

und

net stop [serviceName]

Sagen Sie, ob sie erfolgreich waren oder nicht. Beispielsweise

U:\>net stop alerter
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

Wenn Sie von einer Batch-Datei aus ausführen, haben Sie Zugriff auf das ERRORLEVEL des Rückkehrcodes. 0 zeigt Erfolg an. Alles, was höher ist, weist auf einen Fehler hin.

Als Fledermausdatei error.bat:

@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause

Die Ausgabe sieht folgendermaßen aus:

U:\>error.bat
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

There was a problem
Press any key to continue . . .

Rückkehrcodes

 - 0 = Success
 - 1 = Not Supported
 - 2 = Access Denied
 - 3 = Dependent Services Running
 - 4 = Invalid Service Control
 - 5 = Service Cannot Accept Control
 - 6 = Service Not Active
 - 7 = Service Request Timeout
 - 8 = Unknown Failure
 - 9 = Path Not Found
 - 10 = Service Already Running
 - 11 = Service Database Locked
 - 12 = Service Dependency Deleted
 - 13 = Service Dependency Failure
 - 14 = Service Disabled
 - 15 = Service Logon Failure
 - 16 = Service Marked For Deletion
 - 17 = Service No Thread
 - 18 = Status Circular Dependency
 - 19 = Status Duplicate Name
 - 20 = Status Invalid Name
 - 21 = Status Invalid Parameter 
 - 22 = Status Invalid Service Account
 - 23 = Status Service Exists
 - 24 = Service Already Paused

Bearbeiten 20.04.2015

Rückkehrcodes:

Der Befehl NET gibt die dokumentierten Rückkehrcodes der Win32_Service-Klasse (Dienst nicht aktiv, Zeitlimit für Dienstanforderung usw.) nicht zurück und gibt bei vielen Fehlern einfach Fehlerstufe 2 zurück.

Schauen Sie hier: http://ss64.com/nt/net_service.html

Bill Michell
quelle
1
NET ist nicht nur für die Funktionen Service bezogen , während SC ist nur für Service - bezogene Funktionen.
Wernight
3
Diese Antwort ist besser, da der Befehl "net" blockiert und wartet, bis der Dienst gestartet oder gestoppt wird, bevor das Batch-Skript weiter ausgeführt wird.
Steven
Da (wie in der Bearbeitung angegeben) die meiste Zeit errorlevel2 zurückgegeben wird, erfahren Sie hier, wie Sie das Fehlerergebnis interpretieren .
HeyJude
28

Sie können den Befehl NET START verwenden und dann die Umgebungsvariable ERRORLEVEL überprüfen, z

net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%

Haftungsausschluss: Ich habe dies von oben geschrieben, aber ich denke, es wird funktionieren.

Jonas Gulle
quelle
8

Anstatt Codes zu überprüfen, funktioniert dies auch

net start "Apache tomcat" || goto ExitError

:End  
exit 0  

:ExitError  
echo An error has occurred while starting the tomcat services  
exit 1  
vanval
quelle
7

Ich habe meine persönliche Batch-Datei dafür erstellt. Meine ist etwas anders, kann aber nach Belieben geändert werden. Ich habe dies vor einiger Zeit erstellt, weil ich gelangweilt war und den Menschen eine einfache Möglichkeit bieten wollte, das Beenden, Starten, Stoppen oder die Einstellung auf Auto einzugeben. Diese BAT-Datei fordert Sie lediglich auf, den Dienstnamen einzugeben, und erledigt den Rest für Sie. Ich wusste nicht, dass er nach etwas suchte, das einen Fehler anzeigte, ich muss diesen Teil falsch verstanden haben. Dies kann jedoch normalerweise durch Eingabe von >> output.txt am Ende der Zeile erfolgen.

% Var% ist nur eine Möglichkeit für den Benutzer, seinen eigenen Dienst in diesen einzugeben, anstatt die Bat-Datei jedes Mal ändern zu müssen, wenn Sie einen anderen Dienst starten / stoppen möchten.

Wenn ich falsch liege, kann sich jeder frei fühlen, mich diesbezüglich zu korrigieren.

@echo off
set /p c= Would you like to start a service [Y/N]?
  if /I "%c%" EQU "Y" goto :1
  if /I "%c%" EQU "N" goto :2
    :1  
    set /p var= Service name: 
:2 
set /p c= Would you like to stop a service [Y/N]?
  if /I "%c%" EQU "Y" goto :3
  if /I "%c%" EQU "N" goto :4
    :3  
    set /p var1= Service name:
:4
set /p c= Would you like to disable a service [Y/N]?
  if /I "%c%" EQU "Y" goto :5
  if /I "%c%" EQU "N" goto :6
    :5  
    set /p var2= Service name:
:6 
set /p c= Would you like to set a service to auto [Y/N]?
  if /I "%c%" EQU "Y" goto :7
  if /I "%c%" EQU "N" goto :10
    :7  
    set /p var3= Service name:
:10
sc start %var%
sc stop %var1%
sc config %var2% start=disabled
sc config %var3% start=auto
Nathanial Wilson
quelle
1
In der Regel werden nur Code-Antworten nicht geschätzt. Könnten Sie Ihre Lösung näher erläutern oder einige erläuternde Kommentare hinzufügen?
Ein Ohrwurm
2
Ich habe dies vor einiger Zeit erstellt, weil ich gelangweilt war und den Menschen eine einfache Möglichkeit bieten wollte, das Beenden, Starten, Stoppen oder die Einstellung auf Auto einzugeben. Diese BAT-Datei fordert Sie lediglich auf, den Dienstnamen einzugeben, und erledigt den Rest für Sie.
Nathanial Wilson
6

Die Verwendung der Rückkehrcodes von net startund net stopscheint mir die beste Methode zu sein. Schauen Sie sich das an: Net Start-Rückkehrcodes .

ZombieSheep
quelle
2
Die verlinkte Seite existiert nicht mehr. Als solches ist dies jetzt eher ein Kommentar.
Neolisk
5

Syntax bringt mich immer ... also ...

Hier erfahren Sie explizit, wie Sie einer Batchdatei eine Zeile hinzufügen, die einen Remotedienst (auf einem anderen Computer) beendet, wenn Sie auf beiden Computern Administrator sind, die .bat-Datei als Administrator ausführen und sich die Computer in derselben Domäne befinden. Der Computername folgt dem UNC-Format \ myserver

sc \\ip.ip.ip.ip stop p4_1

In diesem Fall ... war p4_1 sowohl der Dienstname als auch der Anzeigename, wenn Sie die Eigenschaften für den Dienst in Service Manager anzeigen. Sie müssen den Dienstnamen verwenden.

Für Ihre Service Ops-Junkies ... fügen Sie unbedingt Ihren Ursachencode und Kommentar hinzu! dh '4', was 'Geplant' entspricht, und Kommentar 'Server für Wartung stoppen'

sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance
ATSiem
quelle
1
Wie mache ich das, wenn ich zum Anmelden eine andere Benutzer-ID und ein anderes Passwort verwenden muss?
Frantumn
1
Sie werden CMDals anderer Benutzer / andere ID ausgeführt, indem Sie runas /user:Domain\UserName cmdIhr Kennwort eingeben. CMD wird als angegebenes Benutzerkonto ausgeführt.
Benutzer4317867
4

Wir würden gerne glauben, dass "net stop" den Dienst stoppen wird. Leider ist die Realität nicht so schwarz und weiß. Wenn das Beenden des Dienstes lange dauert, wird der Befehl zurückgegeben, bevor der Dienst beendet wurde. Sie werden es jedoch nicht wissen, es sei denn, Sie überprüfen die Fehlerstufe.

Die Lösung scheint darin zu bestehen, nach dem Status des Dienstes zu suchen, bis dieser gestoppt wird, wobei jedes Mal eine Pause eingelegt wird.

Aber dann wieder...

Ich sehe, dass das Beenden des ersten Dienstes lange dauert, dann scheint der "Netzstopp" für einen nachfolgenden Dienst einfach nichts zu bewirken. Sehen Sie sich den Dienst im Dienstmanager an, und sein Status ist immer noch "Gestartet" - keine Änderung in "Stoppen". Ich kann diesen zweiten Dienst jedoch manuell mit dem SCM beenden und er wird in 3 oder 4 Sekunden beendet.

DaveH
quelle
3

oder Sie können den Remote-Dienst mit diesem Cmd starten: sc \\<computer> start <service>

Zwiebelpsy
quelle
3

Ich habe gerade das obige Beispiel von Jonas verwendet und eine vollständige Liste mit 0 bis 24 Fehlerstufen erstellt. Andere Beiträge sind korrekt net startund verwenden net stopnur errorlevel0 für Erfolg und 2 für Misserfolg.

Aber das hat bei mir funktioniert:

net stop postgresql-9.1
if %errorlevel% == 2 echo Access Denied - Could not stop service
if %errorlevel% == 0 echo Service stopped successfully
echo Errorlevel: %errorlevel%

Wechseln Sie stopzu startund funktioniert umgekehrt.

Clinton
quelle
3

Der manuelle Neustart des Dienstes ist in Ordnung - services.msc hat die Schaltfläche "Neustart", aber in der Befehlszeile fehlt sowohl den Befehlen sc als auch net der Schalter "Neustart". Wenn ein Neustart in der cmd / bat-Datei geplant ist, wird der Dienst sofort gestoppt und gestartet, manchmal auch Es wird eine Fehlermeldung angezeigt, da der Dienst noch nicht gestoppt wurde. Das Herunterfahren dauert einige Zeit.

Dies kann zu einem Fehler führen: sc stop sc start

Es ist eine gute Idee, ein Timeout einzufügen. Ich verwende Ping (es pingt alle 1 Sekunde): sc stop ping localhost -n 60 sc start

Kuleris
quelle
2

Hier ist der Windows 10-Befehl zum Starten der Systemwiederherstellung mithilfe eines Stapels:

sc config swprv start= Auto

Diese Befehle können Ihnen auch gefallen:

  • Ändern Sie den Registrierungswert so, dass die Systemwiederherstellung automatisch gestartet wird

    REG ADD "HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ SystemRestore" / v DisableSR / t REG_DWORD / d 0 / f

  • Erstellen Sie einen Systemwiederherstellungspunkt

    Wmic.exe / Namespace: \ root \ default Path SystemRestore Rufen Sie CreateRestorePoint "djibe saved your PC" auf, 100, 12

  • Ändern der Systemwiederherstellung

    vssadmin resize shadowstorage / for = C: / on = C: / maxsize = 10%

Genießen

djibe
quelle
1

SC kann alles mit Diensten machen ... starten, stoppen, prüfen, konfigurieren und mehr ...

Axeman
quelle
1

Manchmal kann man feststellen, dass der Stopp nicht funktioniert.

Mein SQlServer macht das manchmal. Die Verwendung der folgenden Befehlszeile beendet es. Wenn Sie Ihr Skript wirklich wirklich brauchen, um Dinge zu töten, die nicht aufhören. Ich würde es als letzten Ausweg tun lassen

taskkill /pid [pid number] /f
Andrew Pate
quelle
0

Ich schreibe einen Windows-Dienst in C #, die Schleife zum Stoppen / Deinstallieren / Erstellen / Installieren / Starten wurde zu anstrengend. Schrieb ein Miniskript, nannte es reploy.batund legte es in meinem Visual Studio-Ausgabeverzeichnis ab (eines, in dem der erstellte Dienst ausführbar ist), um die Schleife zu automatisieren.

Stellen Sie einfach diese 3 Vars ein

servicename : Dies wird in der Windows-Systemsteuerung (services.msc) angezeigt.

slndir : Ordner (nicht der vollständige Pfad) mit Ihrer Lösungsdatei (.sln)

binpath : vollständiger Pfad (nicht der Ordnerpfad) zur ausführbaren Dienstdatei aus dem Build

ANMERKUNG: Dies muss über die Visual Studio Developer-Befehlszeile ausgeführt werden, damit der msbuildBefehl funktioniert.

SET servicename="My Amazing Service"
SET slndir="C:dir\that\contains\sln\file"
SET binpath="C:path\to\service.exe"
SET currdir=%cd%

call net stop %servicename%
call sc delete %servicename%
cd %slndir%
call msbuild 
cd %bindir%
call sc create %servicename% binpath=%binpath%
call net start %servicename%
cd %currdir%

Vielleicht hilft das jemandem :)

sh87
quelle