代码之家  ›  专栏  ›  技术社区  ›  Onelio

在C#应用程序中进行reg add并在cmd窗口中查询值后出现不同值的原因是什么?

  •  3
  • Onelio  · 技术社区  · 8 年前

    我有一个用C#编写的程序,它打开一个cmd控制台并添加/修改注册表值。

    在控制台输出任务完成后,我用测试 reg query 如果注册表值真的改变了。没有问题。我得到了价值 0x1 正如我所料。

    但当我从当前cmd窗口之外查询此注册表时,就像我作为管理员执行的另一个cmd一样,值为 0x0 在…上 reg查询 .

    这怎么可能?

    这是我的C#代码:

    string command = @"/K reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock /t REG_DWORD /f /v AllowDevelopmentWithoutDevLicense /d 1";
    
            Process proc = Process.Start("cmd.exe", command);
    

    从程序执行的cmd内部查询:

    reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
    
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
        AllowDevelopmentWithoutDevLicense    REG_DWORD    0x1
    

    从外部:

    reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
    
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
        AllowDevelopmentWithoutDevLicense    REG_DWORD    0x0
        AllowAllTrustedApps    REG_DWORD    0x0
    
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense=1
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   Mofi    4 年前

    当64位Windows上的32位应用程序访问注册表项时

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
    

    它由Windows重定向 registry redirector

    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\AppModelUnlock
    

    64位应用程序真正访问

    HKEY_LOCAL_MACHINE\软件\Microsoft\Windows\CurrentVersion\AppModelUnlock
    

    两个注册表路径之间的差异是 Wow6432Node 默认情况下,仅对Windows x64上的64位应用程序可见。

    请参阅Microsoft开发人员文章 Registry Keys Affected by WOW64 .

    有关完整性,另请参见:

    有32位 cmd.exe reg.exe 在64位Windows上 在目录中 %SystemRoot%\SysWow64 存在 %SystemRoot%\System32 适用于32位应用程序和64位 命令提示符 注册.exe 在里面 %系统根%\System32 .

    您的C#应用程序很可能编译为32位应用程序,因此调用32位 命令提示符 它调用32位 注册.exe .

    您可以通过显式调用32位应用程序来解决此问题 %SystemRoot%\Sysnative\cmd.exe .

    但要知道 %SystemRoot%\Sysnative 在32位Windows上不存在,在64位Windows上也不存在64位应用程序。( Sysnative 是一个特殊的别名,而不是硬链接、连接或真正的文件夹。)

    因此,您的32位C#应用程序需要首先检查 %系统根%\Sysnative\cmd.exe 存在,并使用此路径使用64位编辑64位注册表值 cmd reg 。但在32位Windows上 %SystemRoot%\System32.exe\cmd.exe 必须由32位C#应用程序调用。顺便说一句: %SystemRoot% 引用环境变量的值 系统文件夹 .

    另请参阅以下答案:

    注1:

    跑步 命令提示符 根本不需要。可以直接在32位Windows上运行

    %SystemRoot%\System32\reg.exe
    

    或在64位Windows上

    %SystemRoot%\Sysnative\reg.exe
    

    来自32位应用程序。

    注2:

    最后,C#应用程序不需要使用 注册.exe 因为.NET Framework具有访问Windows注册表的内置支持 Registry.SetValue Method Microsoft甚至在示例代码块中添加了一些示例。

    KEY_WOW64_64键 可以在32位应用程序中使用,以始终显式访问64位注册表项,如Microsoft文档页上所述 Accessing an Alternate Registry View .