2010-12-29 41 views
64

Tôi đã viết Dịch vụ Windows hiển thị dịch vụ WCF cho GUI được cài đặt trên cùng một máy. Khi tôi chạy GUI, nếu tôi không thể kết nối với dịch vụ, tôi cần biết liệu đó có phải do ứng dụng dịch vụ chưa được cài đặt hay không, hoặc nếu đó là do dịch vụ không chạy. Nếu trước đây, tôi sẽ muốn cài đặt nó (như được mô tả here); nếu sau này, tôi sẽ muốn khởi động nó.Cách kiểm tra xem dịch vụ cửa sổ có được cài đặt trong C#

Câu hỏi là: làm thế nào để bạn phát hiện nếu dịch vụ được cài đặt, và sau đó phát hiện ra rằng nó đã được cài đặt, bạn khởi động nó như thế nào?

Trả lời

116

Sử dụng:

// add a reference to System.ServiceProcess.dll 
using System.ServiceProcess; 

// ... 
ServiceController ctl = ServiceController.GetServices() 
    .FirstOrDefault(s => s.ServiceName == "myservice"); 
if(ctl==null) 
    Console.WriteLine("Not installed"); 
else  
    Console.WriteLine(ctl.Status); 
+0

+1 Thú vị ... –

+0

Cảm ơn bạn - chỉ là những gì tôi cần! –

+1

+1 Brilliant! Và cảm ơn. –

27

Bạn có thể sử dụng sau đây cũng ..

using System.ServiceProcess; 
... 
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName); 
+1

IMO, đây là cách thanh lịch nhất để kiểm tra xem dịch vụ của bạn có tồn tại không. Chỉ một dòng mã, tận dụng sức mạnh của LINQ. Và bằng cách này, .Any() trả về một bool chính xác những gì bạn muốn khi hỏi một câu hỏi có/không :-) –

+0

Nếu bạn cần kiểm tra các dịch vụ trên máy từ xa, hãy sử dụng ['GetServices (string)'] (https://msdn.microsoft.com/en-us/library/s21fd6th.aspx) – ShooShoSha

2

Đối với phi LINQ, bạn chỉ có thể lặp qua mảng như thế này:

using System.ServiceProcess; 

bool serviceExists = false 
foreach (ServiceController sc in ServiceController.GetServices()) 
{ 
    if (sc.ServiceName == "myServiceName") 
    { 
     //service is found 
     serviceExists = true; 
     break; 
    } 
} 
2

Thực tế lặp như sau:

foreach (ServiceController SC in ServiceController.GetServices()) 

có thể ném ngoại lệ Truy cập bị từ chối nếu tài khoản mà ứng dụng của bạn đang chạy không có quyền xem thuộc tính dịch vụ. Mặt khác, bạn có thể làm điều này một cách an toàn ngay cả khi không có dịch vụ nào có tên như vậy:

ServiceController SC = new ServiceController("AnyServiceName"); 

Nhưng truy cập thuộc tính nếu dịch vụ không tồn tại sẽ dẫn đến InvalidOperationException. Vì vậy, đây là cách an toàn để kiểm tra xem dịch vụ đã được cài đặt chưa:

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(); 
} 
+0

cảm ơn! và bạn muốn kết thúc bằng: cuối cùng { SC.Close(); } – Cel

+2

Tại sao không quấn toàn bộ đồ vật đang sử dụng? Điều đó sẽ loại bỏ nhu cầu cuối cùng {SC.Close()} vì một câu lệnh sử dụng sẽ tự động bỏ đi. sử dụng (ServiceController SC = new ServiceController ("MyServiceName")) – bill

0

Tôi nghĩ đây là câu trả lời hay nhất cho câu hỏi này. Không cần phải thêm xử lý bổ sung để xác minh nếu dịch vụ tồn tại, vì nó sẽ ném một ngoại lệ nếu nó không. Bạn chỉ cần bắt nó. Bạn cũng không cần phải đóng() kết nối nếu bạn bọc toàn bộ phương thức bằng cách sử dụng().

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  
}  
} 
+0

Không phải là một câu trả lời rất tốt cả.(1) Quản lý mã theo ngoại lệ là thực hành rất kém - không hiệu quả và chậm, và (2) câu trả lời được chấp nhận là gọn gàng, súc tích và trả lời các yêu cầu một cách hoàn hảo. Bạn đã nhìn vào nó trước khi lặn với câu trả lời của riêng bạn? –

+0

Rõ ràng bạn không biết cách đọc như câu trả lời được chấp nhận, vì anh ấy đã hỏi rõ ràng về cách bắt đầu dịch vụ, điều này không được bao gồm trong câu trả lời gốc. – bill

+0

Rõ ràng, bạn không biết cách viết mã đúng cách. Như @Shaul Behr đã nói, cách tiếp cận của bạn là thực hành tồi vì nó không hiệu quả và chậm. Nói câu trả lời _own_ của bạn có lẽ là tốt nhất, làm cho nó thậm chí còn tồi tệ hơn: tự khen ngợi không bao giờ được coi là một hành vi tốt ở đây trên SO (và có lẽ trên toàn thế giới, quá). – Yoda

1
private bool ServiceExists(string serviceName) 
    { 
     ServiceController[] services = ServiceController.GetServices(); 
     var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase)); 
     return service != null; 
    } 
Các vấn đề liên quan