为什么尝试更新注册表值失败?

时间:2015-01-21 18:48:37

标签: c# registry regedit registrykey

我有这段代码:

RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Android Studio", true);
myKey.SetValue("StartMenuGroup", "Droidio", RegistryValueKind.String); // was "Android Studio" - change to "Droidio"

...我改编自here

运行它,但会导致以下NRE转储:

*System.NullReferenceException was unhandled
  _HResult=-2147467261
  _message=Object reference not set to an instance of an object.
  HResult=-2147467261
  IsTransient=false
  Message=Object reference not set to an instance of an object.
  Source=Sandbox
  StackTrace:
       at Sandbox.Form1.button57_Click(Object sender, EventArgs e) in c:\HoldingTank\Sandbox\Form1.cs:line 2524
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Sandbox.Program.Main() in c:\HoldingTank\Sandbox\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:* 

我试图更新的注册表设置(作为测试;然后我将其重新设置)在这里:

enter image description here

当注册表项明显存在时,怎么会失败?

更新

我尝试了另一种方法,我改编自here

RegistryKey reg32key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
    RegistryView.Registry32);
RegistryKey reg_32bit_AppKey = 
    reg32key.OpenSubKey(@"HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio");
if (reg_32bit_AppKey != null)
{
    MessageBox.Show(String.Format("value was {0}", 
        reg_32bit_AppKey.GetValue("StartMenuGroup").ToString()));
    reg_32bit_AppKey.SetValue("StartMenuGroup", "Droidio");
    MessageBox.Show(String.Format("value is now {0}", 
        reg_32bit_AppKey.GetValue("StartMenuGroup").ToString()));
}
else
{
    MessageBox.Show("Cannot open registry");
}

...但是,虽然它没有崩溃,但我看到" 无法打开注册表"消息。

更新2

这样(比特加倍):

RegistryKey reg64key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
    RegistryView.Registry64);
RegistryKey reg_64bit_AppKey = 
    reg64key.OpenSubKey(@"HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio");
if (reg_64bit_AppKey != null)
{
    MessageBox.Show(String.Format("value was {0}", 
        reg_64bit_AppKey.GetValue("StartMenuGroup").ToString()));
    reg_64bit_AppKey.SetValue("StartMenuGroup", "Droidio");
    MessageBox.Show(String.Format("value is now {0}", 
        reg_64bit_AppKey.GetValue("StartMenuGroup").ToString()));
}
else
{
    MessageBox.Show("Cannot open registry");
}

...我仍然得到" 无法打开注册表"结果

更新3

好的,将代码更改为此(从替代尝试中删除" HKEY_LOCAL_MACHINE")

RegistryKey reg64key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
    RegistryView.Registry64);
RegistryKey reg_64bit_AppKey = reg64key.OpenSubKey(@"SOFTWARE\Android 
    Studio");
if (reg_64bit_AppKey != null)
{
    MessageBox.Show(String.Format("value was {0}", 
        reg_64bit_AppKey.GetValue("StartMenuGroup").ToString()));
    reg_64bit_AppKey.SetValue("StartMenuGroup", "Droidio");
    MessageBox.Show(String.Format("value is now {0}", 
        reg_64bit_AppKey.GetValue("StartMenuGroup").ToString()));
}
else
{
    MessageBox.Show("Cannot open registry");
}

...更改异常。首先,正如我所看到的,有一些进展," 价值是Android Studio "

...但是它会在下一行中断,即:

reg_64bit_AppKey.SetValue("StartMenuGroup", "Droidio");

...与:

*System.UnauthorizedAccessException was unhandled
  _HResult=-2147024891
  _message=Cannot write to the registry key.
  HResult=-2147024891
  IsTransient=false
  Message=Cannot write to the registry key.
  Source=mscorlib
  StackTrace:
       at System.ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource resource)
       at Microsoft.Win32.RegistryKey.EnsureWriteable()
       at Microsoft.Win32.RegistryKey.SetValue(String name, Object value, RegistryValueKind valueKind)
       at Microsoft.Win32.RegistryKey.SetValue(String name, Object value)
       at Sandbox.Form1.button57_Click(Object sender, EventArgs e) in c:\HoldingTank\Sandbox\Form1.cs:line 2559
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at 
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentM
anager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Sandbox.Program.Main() in c:\HoldingTank\Sandbox\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object 
state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, 
Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:* 

那么为什么我能读,但不能写?我在运行此代码时以管理员模式运行Visual Studio 2013 ...

更新4

现在这是一个未经授权的访问问题。

当我到达设置值的行时,这里是reg_64bit_AppKey的值:

enter image description here

F10通过它咳嗽"未经授权的访问" whin并[g] ING。

更新5

使用此内容创建文件:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio]

"StartMenuGroup"="Droidio"

...命名它" DroidioReg.reg ",并从Windows资源管理器手动选择合并上下文菜单做了我的预期(希望,无论如何):更改了StartMenuGroup&# 39;对于" Droidio"的价值。实际上,即使只是双击文件并浏览所有确认对话框也可以。

所以,这对于N学位来说是愚蠢的,但是有可能以编程方式调用" Merge"在该文件上 - IOW,将该文件放在手持设备上,然后在代码中执行它?用户是否必须浏览警告对话框,或者是否有办法以编程方式阻止显示这些对话框?

2 个答案:

答案 0 :(得分:1)

使用转义字符串而不是字符串文字。 OpenSubKey方法似乎无法正确读取转义路径。

Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Android Studio", true);

答案 1 :(得分:1)

我在Pwninstein的评论中找到了克服访问权限违规here的关键点 - 只需附加一个" true"到OpenSubKey()方法就可以了。

我很害怕,但现在我可以说通过tWotC(群众的智慧)组装的工作代码是:

RegistryKey reg64key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey reg_64bit_AppKey = reg64key.OpenSubKey(@"SOFTWARE\Android Studio", true);
if (reg_64bit_AppKey != null)
{
    //MessageBox.Show(String.Format("value was {0}", reg_64bit_AppKey.GetValue("StartMenuGroup")));
    reg_64bit_AppKey.SetValue("StartMenuGroup", "Droidio", RegistryValueKind.String);
    //MessageBox.Show(String.Format("value is now {0}", reg_64bit_AppKey.GetValue("StartMenuGroup")));
}
else
{
    MessageBox.Show("Cannot open registry");
}

对于我的真实情况,我无疑需要使用32位版本,而不是64位,因为手持设备比Joe Dirt更老,而且两次就是脾气暴躁。