Hinzufügen einer Abhängigkeit von einem Windows-Dienst, NACHDEM der Dienst installiert wurde

133

Ich habe einen Windows-Dienst, der eine SQL Server-Datenbank verwendet. Ich habe keine Kontrolle über die Installation des Dienstes, möchte jedoch eine Abhängigkeit vom Dienst hinzufügen, um sicherzustellen, dass er nach dem Start von SQL Server gestartet wird. (SQL Server läuft auf demselben Rechner wie der betreffende Dienst)

Gibt es ein Tool, um eine Abhängigkeit hinzuzufügen oder möglicherweise die Registrierung direkt zu bearbeiten?

Rick
quelle

Antworten:

199

Dies kann auch über eine Eingabeaufforderung mit erhöhten Rechten mithilfe des scBefehls erfolgen. Die Syntax lautet:

sc config [service name] depend= <Dependencies(separated by / (forward slash))>

Hinweis : Nach dem Gleichheitszeichen ist ein Leerzeichen und davor kein Leerzeichen .

Warnung : Der depend=Parameter überschreibt die vorhandene Abhängigkeitsliste und hängt sie nicht an. Wenn ServiceA beispielsweise bereits von ServiceB und ServiceC abhängt und Sie ausgeführt werden depend= ServiceD, hängt ServiceA jetzt nur von ServiceD ab. (Danke Matt !)

Beispiele

Abhängigkeit von einem anderen Dienst:

sc config ServiceA depend= ServiceB

Oben bedeutet, dass ServiceA erst startet, wenn ServiceB gestartet wurde. Wenn Sie ServiceB beenden, wird ServiceA automatisch beendet.

Abhängigkeit von mehreren anderen Diensten:

sc config ServiceA depend= ServiceB/ServiceC/ServiceD/"Service Name With Spaces"

Oben bedeutet, dass ServiceA erst gestartet wird, wenn ServiceB, ServiceC und ServiceD alle gestartet wurden. Wenn Sie ServiceB, ServiceC oder ServiceD beenden, wird ServiceA automatisch beendet.

So entfernen Sie alle Abhängigkeiten:

sc config ServiceA depend= /

So listen Sie aktuelle Abhängigkeiten auf:

sc qc ServiceA
Pennen
quelle
5
Wenn Sie die vorhandenen Abhängigkeiten anzeigen möchten, bevor Sie sie mit der Kip-Methode ändern, können Sie sc qc YourServiceName
mivk
1
Sei einfach vorsichtig ... Ich habe das gerade benutzt und wusste nicht, dass es bestehende Abhängigkeiten überschreibt. Es gab zwei für meinen Dienst, an die ich mich nicht erinnere. Jetzt sind sie weg. Stellen Sie also sicher, dass Sie den Befehl @mivk ausführen, der zuerst erwähnt wurde, damit alle anderen Abhängigkeiten zuerst angezeigt werden.
Matt
1
Sie können die aktuell konfigurierte Abhängigkeit für einen Dienst mit sc qc [service name]command
gerrytan vom
4
Wenn Ihr Dienst wie ich Leerzeichen im Namen enthält, setzen Sie ihn in Anführungszeichen.
Lazlow
6
Wenn Sie Powershell verwenden, vergewissern Sie sich, dass Sie eine sc.exeandere Methode verwenden. Andernfalls wird der folgende Fehler angezeigt : 'Es kann kein Positionsparameter gefunden werden, der ein Argument akzeptiert'
spuder
42

Sie können Dienstabhängigkeiten hinzufügen, indem Sie dem Dienst in der Registrierung den Wert "DependOnService" mit dem regeditBefehl hinzufügen. Dienste finden Sie unter HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Service name>. Die Details finden Sie im MS KB-Artikel 193888 , aus dem der folgende Auszug stammt:

Um eine neue Abhängigkeit zu erstellen, wählen Sie den Unterschlüssel für den Dienst aus, den Sie verzögern möchten, klicken Sie auf Bearbeiten und dann auf Wert hinzufügen. Erstellen Sie einen neuen Wertname "DependOnService" (ohne die Anführungszeichen) mit einem Datentyp von REG_MULTI_SZ und klicken Sie dann auf OK. Wenn das Dialogfeld Daten angezeigt wird, geben Sie den oder die Namen der Dienste ein, die Sie vor diesem Dienst mit einem Eintrag für jede Zeile starten möchten, und klicken Sie dann auf OK.

pauska
quelle
7
Heiliger Bimbam! Das war die schnellste Antwort, die ich je erhalten habe. Ich bin kaum auf die Homepage zurückgekehrt.
Rick
2

Ich suchte nach einer reinen PowerShell-Methode (keine regedit- oder sc.exe-Methode), die unter 2008R2 / Win7 und neueren Versionen funktioniert.

Mit PowerShell ist es ganz einfach, das Regedit durchzuführen:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation' -Name DependOnService -Value @('Bowser','MRxSmb20','NSI')

Oder mit WMI:

$DependsOn = @('Bowser','MRxSmb20','NSI','') #keep the empty array element at end
$svc = Get-WmiObject win32_Service -filter "Name='LanmanWorkstation'"
$svc.Change($null,$null,$null,$null,$null,$null,$null,$null,$null,$null,$DependsOn)

Die Change- Methode der Win32_Service-Klasse hat auf eine Lösung hingewiesen:

uint32 Change(
[in] string  DisplayName,
[in] string  PathName,
[in] uint32  ServiceType,
[in] uint32  ErrorControl,
[in] string  StartMode,
[in] boolean DesktopInteract,
[in] string  StartName,
[in] string  StartPassword,
[in] string  LoadOrderGroup,
[in] string  LoadOrderGroupDependencies[],
[in] string  ServiceDependencies[]
);
JoeGasper
quelle
1

Ich habe eine einfache .net-Anwendung geschrieben, um Dienstabhängigkeiten zu verwalten, wenn Sie interessiert sind. Es ist kostenlos.

http://webpages.charter.net/bushman4/servicedependencymanager.html

Glenn Sullivan
quelle
1
Es sagt mir, ich brauche .NET 1.1, aber ich laufe Windows 7
Nick
1
.Net 1.1 muss unter Windows 7 installiert sein. Siehe die Antwort auf diese Frage: answers.microsoft.com/en-us/windows/forum/…
Glenn Sullivan
9
Wirklich, 2014 haben Sie empfohlen, .NET 1.1 auf Win7 zu installieren, anstatt es nur für 4.0 neu zu kompilieren? Danke nein
Endrju
0

In C ++ (ATL) hat mir das gefallen

bool ModifyDependOnService(void)
{
  CRegKey R;
  if (ERROR_SUCCESS == R.Open(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\services\\MyService"))
  {
    bool depIsThere = false;

    // determine if otherservice is installed, if yes, then add to dependency list.
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (hSCManager)
    {
      SC_HANDLE hService = OpenService(hSCManager, L"OtherService", SERVICE_QUERY_STATUS);
      if (hService)
      {
        depIsThere = true;
        CloseServiceHandle(hService);
      }
      CloseServiceHandle(hSCManager);
    }

    std::wstring key = L"DependOnService";
    if (depIsThere )
    {
      const wchar_t deps[] = L"RPCSS\0OtherService\0";
      R.SetValue(key.c_str(), REG_MULTI_SZ, deps, sizeof(deps));
    }

    R.Close();
    return true;
  }
  return false;
}
Anders
quelle