Доступ запрещен при использовании system.management для выключения - PullRequest
2 голосов
/ 05 мая 2011

Я пытаюсь создать небольшую программу на C # -MVC # 2008 Express, которая позволит мне удаленно включать и выключать 15 компьютеров, за которыми я отвечаю.Включить их было легко, но отключить их, кажется, немного сложнее.

Во-первых, у меня нет доменов или SharePoint, просто простая рабочая группа на Windows XP.Теперь мне удалось заставить shutdown.exe работать, но я решил, что должно быть решение C #, поэтому после небольшого поиска я нашел некоторый код, использующий пространство имен system.management, которое прекрасно работало.

Единственная проблема с обоими решениями заключается в том, что мне нужно было войти в систему с идентичной учетной записью администратора, и, скажем так, не все, с кем я работаю, разбираются в технологиях, поэтому мысль о том, чтобы позволить им использовать учетную запись администратора, заставляет меня нервничать.

Я мог просто не позволить им получить доступ к этой функции, но я нашел следующий код:

void Shutdown() {
  try
  {
      const string computerName = "PC05"; // 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 = "";
      //options.Password = "";
      //options.Authority = "ntlmdomain:DOMAIN";

      //ManagementScope scope = new ManagementScope("\\\\" + computerName +  "\\root\\cimv2", options);
      ManagementScope scope = new ManagementScope();
      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);
  }
} 

Но я продолжаю получать сообщение об отказе в доступе, когда пытаюсь его использовать.

"Доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))"} System.Exception {System.UnauthorizedAccessException}

Я пытался раскомментировать только пароль и имя пользователя(с пропуском и именем пользователя учетной записи администратора, которую я знаю правильно) также раскомментирует полномочия.Я использовал:

options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;

, но, похоже, ничего не работает.Я не знаю, нужно ли мне устанавливать для этого специальные настройки, но, как я уже сказал, я могу подключиться и завершить работу, если я войду в учетную запись администратора, используемую на другом компьютере.В настоящее время я тестирую в альтернативной учетной записи администратора.

Я прочитал:

http://msdn.microsoft.com/en-us/library/aa393613(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa393266(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa389286(v=VS.85).aspx

http://msdn.microsoft.com/en-us/library/aa389290(VS.85).aspx (честно говоря, не совсем понял)

Возможно, это разрешено только в доменах, но я не нашел подтверждения этому.Я хочу избежать необходимости добавлять другую учетную запись, поэтому есть предложения?

Ответы [ 2 ]

2 голосов
/ 05 октября 2012
ManagementBaseObject outParams = null;
ManagementClass os = new ManagementClass("Win32_OperatingSystem");
os.Get();
os.Scope.Options.EnablePrivileges = true; // enables required security privilege.
ManagementBaseObject inParams = os.GetMethodParameters("Win32Shutdown");
inParams["Flags"] = "2"; // System reboot
inParams["Reserved"] = "0";
foreach (ManagementObject mo in os.GetInstances())
    outParams = mo.InvokeMethod("Win32Shutdown",
    inParams, null);
0 голосов
/ 06 мая 2011

Вот более простой обходной путь, который может быть полезен в вашей ситуации (дайте мне знать, если вы можете использовать это решение):

удаленное отключение (* .bat скрипт) без прав администратора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...