我試圖使用下面的代碼(寫得不好,但它只是一個概念證明)來編輯域上的計算機註冊表。我有一個域帳戶,並且我已驗證域管理員組存在於我試圖影響的計算機上的本地管理員組中。我連接到這些其他機器來執行其他管理類型任務,所以我確信我擁有這些主機的管理權限。WMI:遠程編輯註冊表
根據winerror.h,StdRegProv的所有「get」方法都正常工作(http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx),但「set」或「create」方法以及檢查訪問都返回「Error_Access_Denied」的「5」。所以有這樣的問題:當我試圖修改註冊表時,爲什麼我的訪問被拒絕?如果有人能幫我弄清楚這一點,我會非常感謝!
我差點忘了,當我在本地機器上以管理員模式啓動Visual Studio並在本地機器上運行代碼時,它完美地工作。如果我沒有在本地機器上以管理員模式啓動,則代碼失敗,因此我懷疑可能存在UAC問題?
UPDATE:使用註冊表編輯器並連接到遠程計算機,我可以改變這使我相信這不是一個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();
}
}
好的提示,但不幸的是,UAC需要通過策略在整個域中啓用。另外,註冊表值更改後,計算機是否需要重新啓動? – Quanta 2010-04-02 20:20:43
是的,它需要重新啓動。似乎應該有辦法解決這個問題... – 2010-04-02 20:52:12
您是否嘗試將您的用戶添加到本地管理員組?根據我發佈的鏈接:'如果您的計算機是域的一部分,請使用遠程計算機的本地管理員組中的域帳戶連接到目標計算機。然後,UAC訪問令牌篩選將不會影響本地管理員組中的域帳戶。我不知道在你的情況下這是否可能。 – 2010-04-02 20:54:30