Я пытаюсь использовать следующий код (плохо написанный, но это всего лишь подтверждение концепции) для редактирования реестра компьютера в домене. У меня есть учетная запись домена, и я убедился, что группа администраторов домена присутствует в локальной группе администраторов на машинах, на которые я пытаюсь повлиять. Я подключился к этим другим машинам для выполнения других задач административного типа, поэтому я уверен, что у меня есть права администратора на этих хостах.
Все методы "get" в StdRegProv работают нормально (http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx), но методы "set" или "create", а также проверка доступа ко всем возвращают "5", которое равно "Error_Access_Denied" согласно winerror.h. Так что вот в чем проблема: почему я получаю отказ в доступе при попытке изменить реестр? Если кто-нибудь может помочь мне разобраться в этом, я буду вам очень признателен!
Я почти забыл, когда я запускаю Visual Studio в режиме администратора на своем локальном компьютере и запускаю код на локальном компьютере, он работает безупречно. Если я не запускаюсь в режиме администратора на локальном компьютере, код завершается ошибкой, поэтому я подозреваю, что, возможно, проблема с UAC?
ОБНОВЛЕНИЕ: Используя regedit и подключаясь к удаленному компьютеру, я МОГУ изменить ключ реестра, что наводит меня на мысль, что это не проблема UAC, но она выполняется с локальным соединением WMI при запуске в повышенный режим на моей собственной машине, так что, возможно, это UAC. Кроме того, машины winXP возвращают тот же код ошибки (5, ERROR_ACCESS_DENIED), что приводит меня к мысли, что это не UAC ... это отстой.
решено: объект ManagementClass использует неправильное переопределение; он должен быть параметризован с помощью ManagementScope, в противном случае вы просто выполняете функции локально.
ManagementClass mc = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
Да, я эпический провал: / 9K строк кода, и эта строка подняла меня до самого длинного из них.
using System;
using System.Management;
public class EditRemoteRegistry
{
public static void Main(string[] args)
{
ConnectionOptions options = new ConnectionOptions();
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
options.Password = "password goes here";
//options.Authority = "my company's domain";
//options.Username = "Admin username";
ManagementScope scope = new ManagementScope("\\\\arbitraryhost\\root\\default", options);
scope.Connect();
ManagementClass mc = new ManagementClass("StdRegProv");
ManagementBaseObject inParams = mc.GetMethodParameters("CreateKey");
inParams["hDefKey"] = (UInt32)2147483650;
inParams["sSubKeyName"] = "Software\\Test";
ManagementBaseObject outParams = mc.InvokeMethod("CreateKey", inParams, null);
//Should return a 0, but returns a 5, "Error_Access_Denied"
Console.WriteLine("CreateKey Method returned " + outParams["returnValue"]);
//This chunk works fine
ManagementBaseObject inParams5 = mc.GetMethodParameters("GetDWORDValue");
inParams5["hDefKey"] = 2147483650;
inParams5["sSubKeyName"] = "Software\\Test";
inParams5["sValueName"] = "testDWORDvalue";
ManagementBaseObject outParams5 = mc.InvokeMethod("GetDWORDValue", inParams5, null);
Console.WriteLine("GetDWORDValue returned " + (UInt32)outParams5["returnValue"] + " ");
Console.WriteLine((UInt32)outParams5["uValue"]);
ManagementBaseObject inParams6 = mc.GetMethodParameters("SetStringValue");
inParams6["hDefKey"] = 2147483650;
inParams6["sSubKeyName"] = "Software\\Test";
inParams6["sValueName"] = "TestStringValue";
inParams6["sValue"] = "Hello World!";
ManagementBaseObject outParams6 = mc.InvokeMethod("SetStringValue", inParams6, null);
//Should return a 0, but returns a 5, "Error_Access_Denied"
Console.WriteLine("SetStringValue returned " + outParams6["returnValue"]);
Console.ReadKey();
}
}