2010-05-27 36 views
12

tôi tìm thấy mã này trên một chủ đề cũ để shutdown máy tính cục bộ:WMI để khởi động lại máy từ xa

using System.Management; 

void Shutdown() 
{ 
    ManagementBaseObject mboShutdown = null; 
    ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem"); 
    mcWin32.Get(); 

    // You can't shutdown without security privileges 
    mcWin32.Scope.Options.EnablePrivileges = true; 
    ManagementBaseObject mboShutdownParams = 
      mcWin32.GetMethodParameters("Win32Shutdown"); 

    // Flag 1 means we want to shut down the system. Use "2" to reboot. 
    mboShutdownParams["Flags"] = "1"; 
    mboShutdownParams["Reserved"] = "0"; 
    foreach (ManagementObject manObj in mcWin32.GetInstances()) 
    { 
     mboShutdown = manObj.InvokeMethod("Win32Shutdown", 
             mboShutdownParams, null); 
    } 
} 

Có thể sử dụng một phương pháp WMI tương tự như khởi động lại cờ "2" một máy từ xa, mà tôi chỉ có tên máy chứ không phải IPaddress.

EDIT: Tôi hiện có:

SearchResultCollection allMachinesCollected = machineSearch.FindAll(); 
Methods myMethods = new Methods(); 
string pcName; 
ArrayList allComputers = new ArrayList(); 
foreach (SearchResult oneMachine in allMachinesCollected) 
{ 
    //pcName = oneMachine.Properties.PropertyNames.ToString(); 
    pcName = oneMachine.Properties["name"][0].ToString(); 
    allComputers.Add(pcName); 
    MessageBox.Show(pcName + "has been sent the restart command."); 
    Process.Start("shutdown.exe", "-r -f -t 0 -m \\" + pcName); 
} 

nhưng điều này không làm việc, và tôi muốn WMI đi về phía trước.

Trả lời

14

Để giải quyết các truy vấn WMI với máy tính từ xa, bạn chỉ cần chỉ định tên máy tính (hoặc địa chỉ IP) trong đối tượng ManagementScope.

Tôi không giỏi trong C#, nhưng đây là một ví dụ tôi đã sử dụng MSDN và WMI Code Creator (đó là, một công cụ tuyệt vời để tạo mã WMI và hỗ trợ C# trong số những người khác). Hy vọng mã này sẽ cho bạn ý tưởng.

(Disclaimer:. Mã này là chưa được kiểm tra)

using System; 
using System.Management; 
... 

void Shutdown() 
{ 
    try 
    { 
     const string computerName = "COMPUTER"; // computer name or IP address 

     ConnectionOptions options = new ConnectionOptions(); 
     options.EnablePrivileges = true; 
     // To connect to the remote computer using a different account, specify these values: 
     // options.Username = "USERNAME"; 
     // options.Password = "PASSWORD"; 
     // options.Authority = "ntlmdomain:DOMAIN"; 

     ManagementScope scope = new ManagementScope(
      "\\\\" + computerName + "\\root\\CIMV2", options); 
     scope.Connect(); 

     SelectQuery query = new SelectQuery("Win32_OperatingSystem"); 
     ManagementObjectSearcher searcher = 
      new ManagementObjectSearcher(scope, query); 

     foreach (ManagementObject os in searcher.Get()) 
     { 
      // Obtain in-parameters for the method 
      ManagementBaseObject inParams = 
       os.GetMethodParameters("Win32Shutdown"); 

      // Add the input parameters. 
      inParams["Flags"] = 2; 

      // Execute the method and obtain the return values. 
      ManagementBaseObject outParams = 
       os.InvokeMethod("Win32Shutdown", inParams, null); 
     } 
    } 
    catch(ManagementException err) 
    { 
     MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message); 
    } 
    catch(System.UnauthorizedAccessException unauthorizedErr) 
    { 
     MessageBox.Show("Connection error (user name or password might be incorrect): " + unauthorizedErr.Message); 
    } 
} 
+2

Để tham khảo, các "Flags" giá trị của 2 là những gì biến yêu cầu tắt máy này thành khởi động lại. Danh sách đầy đủ các lá cờ ở đây: https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx – Ceilingfish

4

Tôi cũng gặp sự cố với điều này. WMI có thể gây nhầm lẫn với các phương thức cho các lớp và đối tượng. Giải pháp của tôi là dành cho khởi động lại một host trên mạng với C# và WMI, nhưng có thể dễ dàng đơn giản hóa cho máy tính cục bộ:

private void rebootHost(string hostName) 
{ 
    string adsiPath = string.Format(@"\\{0}\root\cimv2", hostName); 
    ManagementScope scope = new ManagementScope(adsiPath); 
    // I've seen this, but I found not necessary: 
    // scope.Options.EnablePrivileges = true; 
    ManagementPath osPath = new ManagementPath("Win32_OperatingSystem"); 
    ManagementClass os = new ManagementClass(scope, osPath, null); 

    ManagementObjectCollection instances; 
    try 
    { 
     instances = os.GetInstances(); 
    } 
    catch (UnauthorizedAccessException exception) 
    { 
     throw new MyException("Not permitted to reboot the host: " + hostName, exception); 
    } 
    catch (COMException exception) 
    { 
     if (exception.ErrorCode == -2147023174) 
     { 
      throw new MyException("Could not reach the target host: " + hostName, exception); 
     } 
     throw; // Unhandled 
    } 
    foreach (ManagementObject instance in instances) 
    { 
     object result = instance.InvokeMethod("Reboot", new object[] { }); 
     uint returnValue = (uint)result; 

     if (returnValue != 0) 
     { 
      throw new MyException("Failed to reboot host: " + hostName); 
     } 
    } 
} 
+0

Tôi tìm thấy phương pháp này hoạt động trên máy ảo Azure miễn là máy đang ở trên cùng VPN. Câu trả lời được chấp nhận đã không làm điều đó vì một lý do nào đó. – user3841460

0

này sẽ làm việc như sharm

gwmi win32_operatingsystem -ComputerName xxxxxxxxxxxx | Invoke-WmiMethod -Name reboot 
Các vấn đề liên quan