Ich habe einen Windows-Dienst geschrieben, der einen WCF-Dienst einer auf demselben Computer installierten GUI zur Verfügung stellt. Wenn ich die GUI ausführe und keine Verbindung zum Dienst herstellen kann, muss ich wissen, ob die Dienst-App noch nicht installiert wurde oder ob der Dienst nicht ausgeführt wird. Wenn erstere, möchte ich es installieren (wie hier beschrieben ); Wenn letzteres der Fall ist, möchte ich es starten.
Die Frage ist: Wie erkennen Sie, ob der Dienst installiert ist, und wie starten Sie ihn, nachdem Sie festgestellt haben, dass er installiert ist?
c#
wcf
windows-services
Shaul Behr
quelle
quelle
.GetServices()
100ServiceController
Objekte zurückgegeben werden und Sie eines von hundert Objekten entsorgt haben, während Sie den Rest ignoriert haben, ist das wirklich spürbar besser? Das würde ich selbst nicht sagen.Sie können auch Folgendes verwenden:
using System.ServiceProcess; ... var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
quelle
GetServices(string)
Eigentlich Schleife wie folgt:
foreach (ServiceController SC in ServiceController.GetServices())
kann die Ausnahme "Zugriff verweigert" auslösen, wenn das Konto, unter dem Ihre Anwendung ausgeführt wird, nicht zum Anzeigen von Diensteigenschaften berechtigt ist. Auf der anderen Seite können Sie dies sicher tun, auch wenn kein Dienst mit einem solchen Namen vorhanden ist:
ServiceController SC = new ServiceController("AnyServiceName");
Der Zugriff auf seine Eigenschaften, wenn kein Dienst vorhanden ist, führt jedoch zu InvalidOperationException. Hier ist eine sichere Methode, um zu überprüfen, ob ein Dienst installiert ist:
ServiceController SC = new ServiceController("MyServiceName"); bool ServiceIsInstalled = false; try { // actually we need to try access ANY of service properties // at least once to trigger an exception // not neccessarily its name string ServiceName = SC.DisplayName; ServiceIsInstalled = true; } catch (InvalidOperationException) { } finally { SC.Close(); }
quelle
Für Nicht-Linq können Sie das Array einfach wie folgt durchlaufen:
using System.ServiceProcess; bool serviceExists = false foreach (ServiceController sc in ServiceController.GetServices()) { if (sc.ServiceName == "myServiceName") { //service is found serviceExists = true; break; } }
quelle
Ich denke, das ist die beste Antwort auf diese Frage. Es ist nicht erforderlich, zusätzliche Verarbeitung hinzuzufügen, um zu überprüfen, ob der Dienst vorhanden ist, da sonst eine Ausnahme ausgelöst wird. Sie müssen es nur fangen. Sie müssen die Verbindung auch nicht schließen (), wenn Sie die gesamte Methode mit using () umschließen.
using (ServiceController sc = new ServiceController(ServiceName)) { try { if (sc.Status != ServiceControllerStatus.Running) { sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10)); //service is now Started } else //Service was already started } catch (System.ServiceProcess.TimeoutException) { //Service was stopped but could not restart (10 second timeout) } catch (InvalidOperationException) { //This Service does not exist } }
quelle
private bool ServiceExists(string serviceName) { ServiceController[] services = ServiceController.GetServices(); var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase)); return service != null; }
quelle