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

C# 为什么更新注册表值的尝试失败?,c#,registry,regedit,registrykey,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" …我从中改编 但运行它会导致以下NRE转储: *System.NullR

我有以下代码:

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

但运行它会导致以下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:* 
我正在尝试更新的注册表设置(作为测试;然后将其设置回原位)如下所示:

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

更新 我尝试了另一种方法,我采用了:

…但是,虽然它没有崩溃,但我看到了“无法打开注册表”消息

更新2 有了这个(咬口加倍):

…我仍然得到“无法打开注册表”的结果

更新3 好的,将代码更改为此(从替代尝试中删除“HKEY_LOCAL_MACHINE”):

…更改异常。不过,首先,正如我所看到的,“价值来自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_64位_AppKey的值:

F10通过它会发出“未经授权的访问”的呜呜声

更新5 创建包含此内容的文件:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio]

"StartMenuGroup"="Droidio"
…将其命名为“droidireg.reg”,并从Windows资源管理器中手动选择合并上下文菜单,实现了我的预期(无论如何,希望如此):将StartMenuGroup的值更改为“Droidio”。事实上,即使只需在文件上单击两下,并在所有确认对话框中移动,也可以工作


所以,这是第n级的困难,但是有没有可能通过编程在该文件上调用“Merge”-IOW,将该文件放在手持设备上,然后在代码中执行它?用户是否必须浏览警告对话框,或者是否有方法通过编程防止这些对话框显示?

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

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

我在Pwninstein的一篇评论中找到了克服访问权限冲突的关键点——只需在OpenSubKey()方法中添加一个“true”即可

我被吓坏了,但现在我可以欢呼通过tWotC(群众的智慧)组装的工作代码是:


就我的实际情况而言,我无疑需要使用32位版本,而不是64位版本,因为手持设备比Joe Dirth更旧,而且更难操作。

您使用的是64位操作系统吗?应用程序是以32位还是64位运行的?我认为我运行此测试的操作系统是64位的,是的;不过,最终的目标是手持设备(WindowsCE)。我不知道如何确定/指定应用程序是以32位还是64位运行。在64位操作系统上,有两个注册表视图。一个用于32位应用程序,一个用于64位应用程序。您可以使用
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,RegistryView.Registry64)
指定特定视图,该视图将始终打开64位视图,这可能就是您看到的。如果当前系统是64位的,我可能会同时检查这两个系统;登记处恨我!子键是
@“Software\Android Studio”
而不是
@“HKEY\U LOCAL\u MACHINE\Software\Android Studio”
。谢谢,但我还是得到了一个NRE。我没有说在你的字符串中使用HKEY\U LOCAL\u MACHINE\Software\Android Studio。这个…@“HKEY\U LOCAL\u MACHINE\Android Studio”应该是“Software\Android Studio”这就是我所拥有的:RegistryKey myKey=Registry.LocalMachine.OpenSubKey(@“SOFTWARE\Android Studio”,true);SetValue(“StartMenuGroup”、“Droidio”、RegistryValueKind.String);为“myKey”创建一个“Watch”并在行上创建断点…'设置值(“StartMenuGroup”、“Droidio”、RegistryValueKind.String);',并验证“myKey”实际上为空。它可能不是罪魁祸首。
*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:* 
REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio]

"StartMenuGroup"="Droidio"
Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Android Studio", true);
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");
}