C# WinForm管理员权限运行时注册表数据未写入指定路径且多处存储问题
问题解答
1. regedit版本使用说明
你使用的两个注册表编辑器版本都是正确的,64位Windows系统中:
c:\Windows\regedit.exe是64位注册表编辑器,可以查看64位原生注册表节点%systemroot%\syswow64\regedit.exe是32位注册表编辑器,仅能查看32位注册表节点(默认映射到Wow6432Node路径下)
两者配合查看注册表的操作不存在问题。
2. 数据写入到VirtualStore路径的原因
你看到的四个路径本质是注册表虚拟化机制生成的同一存储位置的不同映射入口,并没有实际写入四份数据,触发该机制的原因如下:
Windows为了兼容未适配UAC权限体系的旧程序,默认对未明确声明管理员权限的32位程序,开启注册表/文件系统虚拟化:当程序尝试写入HKEY_LOCAL_MACHINE等系统级路径但没有实际写入权限时,系统会自动将写入操作重定向到当前用户的VirtualStore虚拟存储路径,程序读取时也会优先读取该虚拟路径下的内容,所以你会出现「程序能正常读写但目标HKLM路径找不到数据」的现象。
3. 写入指定HKLM路径的解决方案
按以下步骤操作即可实现直接写入目标路径:
- 第一步:给WinForm程序添加UAC应用清单,关闭注册表虚拟化
在Visual Studio中右键项目 → 添加 → 新建项 → 选择「应用程序清单文件(app.manifest)」,打开文件后找到如下节点:
修改为:<requestedExecutionLevel level="asInvoker" uiAccess="false" />
重新编译程序后,程序运行时会主动请求管理员权限,同时系统会关闭该程序的注册表虚拟化机制。<requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> - 第二步:适配64位注册表访问(按需选择)
- 如果你的程序编译为64位(平台目标设为x64),直接按原有逻辑写入
HKEY_LOCAL_MACHINE\SOFTWARE\MyCompanyName\MyAppName\Licences即可,写入完成后用64位regedit即可在目标路径看到数据 - 如果你的程序需要保留32位运行(平台目标设为x86),需要主动指定访问64位注册表视图,参考代码如下:
using Microsoft.Win32; // 打开64位视图下的HKLM根节点 using (var hklmRoot = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) { // 创建/打开目标子项,第二个参数true表示获取写入权限 using (var licenceKey = hklmRoot.CreateSubKey(@"SOFTWARE\MyCompanyName\MyAppName\Licences", true)) { // 写入许可证数据 licenceKey.SetValue("ActiveKey", "你的许可证密钥内容"); } } - 如果你的程序编译为64位(平台目标设为x64),直接按原有逻辑写入
如果不需要写入原生64位路径,接受写入到Wow6432Node下的32位注册表路径,只做第一步清单修改即可满足需求。
内容的提问来源于stack exchange,提问作者Mark Roworth
相关产品推荐
相关产品推荐

