Napisałem usługę Windows, która uwidacznia usługę WCF do GUI zainstalowanego na tym samym komputerze. Kiedy uruchamiam GUI, jeśli nie mogę połączyć się z usługą, muszę wiedzieć, czy dzieje się tak dlatego, że aplikacja usługi nie została jeszcze zainstalowana, czy też dlatego, że usługa nie działa. Jeśli pierwszy, będę chciał go zainstalować (jak opisano tutaj ); jeśli to drugie, będę chciał go uruchomić.
Pytanie brzmi: w jaki sposób wykryjesz, czy usługa jest zainstalowana, a następnie po wykryciu, że jest zainstalowana, jak ją uruchomić?
c#
wcf
windows-services
Shaul Behr
źródło
źródło
.GetServices()
zwróci 100ServiceController
obiektów i pozbyłeś się jednego na sto, ignorując resztę, czy to naprawdę znacznie lepsze? Sam bym tego nie powiedział.Możesz również użyć następujących.
using System.ServiceProcess; ... var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
źródło
GetServices(string)
Właściwie zapętlony w ten sposób:
foreach (ServiceController SC in ServiceController.GetServices())
może zgłosić wyjątek Odmowa dostępu, jeśli konto, na którym działa aplikacja, nie ma uprawnień do wyświetlania właściwości usługi. Z drugiej strony możesz to bezpiecznie zrobić, nawet jeśli nie istnieje usługa o takiej nazwie:
ServiceController SC = new ServiceController("AnyServiceName");
Ale dostęp do jego właściwości, jeśli usługa nie istnieje, spowoduje InvalidOperationException. Oto bezpieczny sposób sprawdzenia, czy usługa jest zainstalowana:
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(); }
źródło
Dla non-linq możesz po prostu iterować przez tablicę w następujący sposób:
using System.ServiceProcess; bool serviceExists = false foreach (ServiceController sc in ServiceController.GetServices()) { if (sc.ServiceName == "myServiceName") { //service is found serviceExists = true; break; } }
źródło
Myślę, że to najlepsza odpowiedź na to pytanie. Nie ma potrzeby dodawania dodatkowego przetwarzania, aby sprawdzić, czy usługa istnieje, ponieważ zgłosi wyjątek, jeśli tak nie jest. Po prostu musisz to złapać. Nie musisz również zamykać () łączenia, jeśli zawiniesz całą metodę za pomocą ().
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 } }
źródło
private bool ServiceExists(string serviceName) { ServiceController[] services = ServiceController.GetServices(); var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase)); return service != null; }
źródło