2009-08-26 38 views
14

Tôi đang sử dụng mã sau.Kiểm tra trạng thái dịch vụ chạy trên máy tính từ xa bằng C#

ServiceController MyController = new ServiceController(); 
MyController.MachineName = server_txt.Text.Trim(); 
MyController.ServiceName = "Service1"; 

string msg = MyController.Status.ToString(); 
Label1.Text = msg; 

Mã này hoạt động tốt cho các máy tính mạng mà tôi có quyền truy cập. Làm thế nào để thay đổi điều này để nó hoạt động cho các hệ thống trong các lĩnh vực khác nhau bằng cách sử dụng thông tin đăng nhập?

+0

Có thể thử làm như vậy với WMI –

Trả lời

0

Here's a link cho người nào đó đang thử cách tiếp cận tương tự; phát hiện của họ là họ cần đăng nhập trên máy từ xa khớp với thông tin đăng nhập trên máy đang chạy chương trình.

+0

Các câu trả lời chỉ liên kết được khuyến khích. VÌ THẾ. có nghĩa là tham chiếu - không thể nếu nội dung được liên kết đến từng được di chuyển/lưu trữ, tạo liên kết bị hỏng. Bạn nên tóm tắt nội dung và đăng nó ở đây. – vapcguy

11

Nếu bạn sử dụng WMI, bạn có thể đặt thông tin đăng nhập trong 'ConnectionOptions'.

ConnectionOptions op = new ConnectionOptions(); 
op.Username = "Domain\\Domainuser"; 
op.Password = "password"; 
ManagementScope scope = new ManagementScope(@"\\Servername.Domain\root\cimv2", op); 
scope.Connect(); 
ManagementPath path = new ManagementPath("Win32_Service"); 
ManagementClass services; 
services = new ManagementClass(scope, path, null); 

foreach (ManagementObject service in services.GetInstances()) 
{ 

if (service.GetPropertyValue("State").ToString().ToLower().Equals("running")) 
{ // Do something } 

} 
+0

Nó chắc chắn hoạt động. Vui lòng giải thích nó khác biệt như thế nào từ đoạn mã được đăng bởi OP? Ngoài ra, chúng tôi có thể bắt đầu hoặc ngừng dịch vụ bằng phương pháp này không? –

+2

@ViralJain Nó sử dụng WMI thay vì lớp ServiceController. Lớp ServiceController không có tùy chọn người dùng và cách duy nhất là sử dụng Mạo danh với nó. Có, có thể bắt đầu/dừng/tạm dừng vv với WMI. Bạn có thể tìm thấy một ví dụ tốt trong codeproject: http://www.codeproject.com/Articles/28161/Using-WMI-to-manipulate-services-Install-Uninstall – user797717

3

MSDN là bạn của bạn.

using System.ServiceProcess; 

ServiceController sc = new ServiceController("YourService", "MachineName"); 
if (sc.Status.Equals(ServiceControllerStatus.Stopped) || 
    sc.Status.Equals(ServiceControllerStatus.StopPending) 
{ 
    // it is stopped 
} 

Tôi biết rằng nếu bạn có đặc quyền quản trị trên máy đó, chỉ cần mã ở trên. Tuy nhiên, như đã đề cập trong các bình luận khác, bạn có thể sẽ phải thiết lập này lên với mạo danh nếu tài khoản của bạn đang chạy dưới không có đặc quyền quản trị trên máy đó, như vậy:

string userName = "domain\\user"; // there's really just one slash, 
//but you have to escape it if hard-coding.. 
//if brought in by a text box, it would be just domain\user 

string password = "whatever"; 

WindowsImpersonationContext adminContext = Impersonation.getWic(userName, password); 
if (adminContext != null) 
{ 
    try 
    { 
     ServiceController sc = new ServiceController("YourService", "MachineName"); 
     if (sc.Status.Equals(ServiceControllerStatus.Stopped) || 
      sc.Status.Equals(ServiceControllerStatus.StopPending) 
     { 
      // it is stopped 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.Out.WriteLine("\nUnable to set profile to Mandatory:\n\t" + ex.Message); 
     Impersonation.endImpersonation(); 
     adminContext.Undo(); 
    } 
    finally 
    { 
     Impersonation.endImpersonation(); 
     // The above line just basically does this on the tokens --    
     //if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); 
     adminContext.Undo(); 
    } 
} 

Đây là lớp Mạo danh riêng của tôi . Nó có 2 điểm vào chính, getWic()doImpersonation() - getWic() sẽ mất một tên người dùng mà trông giống như domain\user hoặc machinename\user và chia chúng thành các bộ phận cấu thành của họ trước khi trao nó đi để doImpersonation(), trong khi doImpersonation() chấp nhận những phần đã được chia, nếu bạn có nó như vậy và không cần mã số trong getWic(). Cả hai đều trả về WindowsImpersonationContext.

using System; 
using System.Data; 
using System.Configuration; 
using System.Security.Permissions; 
using System.Security.Principal; 
using System.Runtime.InteropServices; 

[assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)] 
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")] 
public class Impersonation 
{ 
    [DllImport("advapi32.dll", EntryPoint = "LogonUser")] 
    public static extern bool LogonUser(
     string lpszUsername, 
     string lpszDomain, 
     string lpszPassword, 
     int dwLogonType, 
     int dwLogonProvider, 
     ref IntPtr phToken); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
     int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public extern static bool CloseHandle(IntPtr handle); 

    // Declare the Logon Types as constants 
    const int LOGON32_LOGON_INTERACTIVE = 2; 
    const int LOGON32_LOGON_NETWORK = 3; 
    const int LOGON32_LOGON_BATCH = 4; 
    const int LOGON32_LOGON_SERVICE = 5; 
    const int LOGON32_LOGON_UNLOCK = 7; 
    const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; // Win2K or higher 
    const int LOGON32_LOGON_NEW_CREDENTIALS = 9; // Win2K or higher 

    // Declare the Logon Providers as constants 
    const int LOGON32_PROVIDER_DEFAULT = 0; 
    const int LOGON32_PROVIDER_WINNT50 = 3; 
    const int LOGON32_PROVIDER_WINNT40 = 2; 
    const int LOGON32_PROVIDER_WINNT35 = 1; 

    // Declare the Impersonation Levels as constants 
    const int SecurityAnonymous = 0; 
    const int SecurityIdentification = 1; 
    const int SecurityImpersonation = 2; 
    const int SecurityDelegation = 3; 

    private static WindowsIdentity newId; 
    private static IntPtr tokenHandle = new IntPtr(0); 
    private static IntPtr dupeTokenHandle = new IntPtr(0); 

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
    public static WindowsImpersonationContext doImpersonation(string svcUserName, string domainName, string password) 
    { 
     // Initialize tokens 
     tokenHandle = IntPtr.Zero; 
     dupeTokenHandle = IntPtr.Zero; 

     // Call LogonUser to obtain a handle to an access token 
     bool returnValue = LogonUser(svcUserName, domainName, password, 
     LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_WINNT50, ref tokenHandle); 

     if (returnValue == false) 
     { 
      int ret = Marshal.GetLastWin32Error(); 

      //Check for errors 
      if (ret != NO_ERROR) 
       throw new Exception("LogonUser failed with error code : " + GetError(ret)); 
     } 

     bool retVal = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle); 
     if (retVal == false) 
     { 
      CloseHandle(tokenHandle); 
      throw new Exception("Exception thrown in trying to duplicate token."); 
     } 
     else 
     { 
      // Begin Impersonation 
      bool bRetVal = DuplicateToken(tokenHandle, 
      (int)SecurityImpersonation, ref dupeTokenHandle); 

      newId = new WindowsIdentity(dupeTokenHandle); 
      WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 
      return impersonatedUser; 
     } 
    } 

    public static void endImpersonation() 
    { 
     if (dupeTokenHandle != IntPtr.Zero) 
      CloseHandle(dupeTokenHandle); 
     if (tokenHandle != IntPtr.Zero) 
      CloseHandle(tokenHandle); 
    } 

    public static WindowsImpersonationContext getWic(string userNameStringFromTextbox, string password) 
    { 
     try 
     { 
      // Establish impersonation 
      string svcUser = userNameStringFromTextbox; 
      string[] arrUser = new string[2]; 
      arrUser = svcUser.Split('\\'); 
      string domain = arrUser[0]; 
      string svcUserName = arrUser[1]; 

      // Get Password: Convert from Base-64 String to decrypted string    
      //string keyLength = ConfigurationManager.AppSettings["keyLength"].ToString(); 
      //string keyLocation = ConfigurationManager.AppSettings["keyLocation"].ToString(); 
      //password = RSAEncrypt.DecryptData(password, keyLength, keyLocation); 

      WindowsImpersonationContext wic = doImpersonation(svcUserName, domain, password); 
      return wic; 
     } 
     catch (Exception ex) 
     { 
      ErrorLog.ErrorRoutine(new Exception("getWic() Error: " + ex.ToString()), ErrorMessage.NOTIFY_APP_ERROR); 
      return null; 
     } 
    } 

    #region Errors 
    const int NO_ERROR = 0; 

    const int ERROR_ACCESS_DENIED = 5; 
    const int ERROR_ALREADY_ASSIGNED = 85; 
    const int ERROR_BAD_DEVICE = 1200; 
    const int ERROR_BAD_NET_NAME = 67; 
    const int ERROR_BAD_PROVIDER = 1204; 
    const int ERROR_CANCELLED = 1223; 
    const int ERROR_EXTENDED_ERROR = 1208; 
    const int ERROR_INVALID_ADDRESS = 487; 
    const int ERROR_INVALID_PARAMETER = 87; 
    const int ERROR_INVALID_PASSWORD = 1216; 
    const int ERROR_MORE_DATA = 234; 
    const int ERROR_NO_MORE_ITEMS = 259; 
    const int ERROR_NO_NET_OR_BAD_PATH = 1203; 
    const int ERROR_NO_NETWORK = 1222; 
    const int ERROR_SESSION_CREDENTIAL_CONFLICT = 1219; 

    const int ERROR_BAD_PROFILE = 1206; 
    const int ERROR_CANNOT_OPEN_PROFILE = 1205; 
    const int ERROR_DEVICE_IN_USE = 2404; 
    const int ERROR_NOT_CONNECTED = 2250; 
    const int ERROR_OPEN_FILES = 2401; 

    private struct ErrorClass 
    { 
     public int num; 
     public string message; 
     public ErrorClass(int num, string message) 
     { 
      this.num = num; 
      this.message = message; 
     } 
    } 

    private static ErrorClass[] ERROR_LIST = new ErrorClass[] { 
     new ErrorClass(ERROR_ACCESS_DENIED, "Error: Access Denied"), 
     new ErrorClass(ERROR_ALREADY_ASSIGNED, "Error: Already Assigned"), 
     new ErrorClass(ERROR_BAD_DEVICE, "Error: Bad Device"), 
     new ErrorClass(ERROR_BAD_NET_NAME, "Error: Bad Net Name"), 
     new ErrorClass(ERROR_BAD_PROVIDER, "Error: Bad Provider"), 
     new ErrorClass(ERROR_CANCELLED, "Error: Cancelled"), 
     new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"), 
     new ErrorClass(ERROR_INVALID_ADDRESS, "Error: Invalid Address"), 
     new ErrorClass(ERROR_INVALID_PARAMETER, "Error: Invalid Parameter"), 
     new ErrorClass(ERROR_INVALID_PASSWORD, "Error: Invalid Password"), 
     new ErrorClass(ERROR_MORE_DATA, "Error: More Data"), 
     new ErrorClass(ERROR_NO_MORE_ITEMS, "Error: No More Items"), 
     new ErrorClass(ERROR_NO_NET_OR_BAD_PATH, "Error: No Net Or Bad Path"), 
     new ErrorClass(ERROR_NO_NETWORK, "Error: No Network"), 
     new ErrorClass(ERROR_BAD_PROFILE, "Error: Bad Profile"), 
     new ErrorClass(ERROR_CANNOT_OPEN_PROFILE, "Error: Cannot Open Profile"), 
     new ErrorClass(ERROR_DEVICE_IN_USE, "Error: Device In Use"), 
     new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"), 
     new ErrorClass(ERROR_NOT_CONNECTED, "Error: Not Connected"), 
     new ErrorClass(ERROR_OPEN_FILES, "Error: Open Files"), 
     new ErrorClass(ERROR_SESSION_CREDENTIAL_CONFLICT, "Error: Credential Conflict"), 
    }; 

    private static string GetError(int errNum) 
    { 
     foreach (ErrorClass er in ERROR_LIST) 
     { 
      if (er.num == errNum) return er.message; 
     } 
     return "Error: Unknown, " + errNum; 
    } 
    #endregion 
} 

Tài liệu tham khảo:
ServiceController Class. https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller(v=vs.110).aspx
WindowsIdentity.Impersonate Method. https://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.110).aspx

Các vấn đề liên quan