使用 getRuntime().exec(cmd) 更改注册表项的值不会更改注册表值,即使操作成功结束

Changing value of registry key with getRuntime().exec(cmd) does not change registry value even the operation ended successfully

我正在尝试从我的 Java 应用程序更改注册表值。我使用命令:

LoudnessEqualizationToggle.execCmdNoReturn("reg add \"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\"+guid+"\FxProperties\""
                                           + " /f /v \"{E0A941A0-88A2-4df5-8D6B-DD20BB06E8FB},4\" /t REG_DWORD /d \""+((activateLEOnKey) ? 1 : 0)+"\"");

Where guid is {d348b8e8-3118-4a9c-9b43-422647b555ca}

activateLEOnKey is boolean value

execCmdNoReturn 函数:

public static final void execCmdNoReturn(String cmd)  {

        try {
            Scanner s = new Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\A");

            System.out.println("Command:"+cmd);
            System.out.println("Printing executed data");

            while (s.hasNext()) {
                System.out.println(s.next());
            }
        } catch (IOException ex) {

            Logger.getLogger(LoudnessEqualizationToggle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

一切正常。我将输出输出到命令提示符:

The operation completed successfully

所以我开始 regedit 来验证值是否已更改,但令我惊讶的是没有任何变化。该值与之前相同。

我有权限吗?是
我使用批处理文件以 运行 作为管理员.

执行我的应用程序

批处理文件:

cd %~dp0
java -jar LoudnessEqualizationToggle.jar
pause

从中创建快捷方式并运行作为管理员。

您是该密钥的所有者吗?是

我用批处理文件测试了我的命令和权限,测试 Windows 注册表中的当前值 0 是否可以按预期更改为 1

该测试的批处理文件是:

cd %~dp0
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{d348b8e8-3118-4a9c-9b43-422647b555ca}\FxProperties" /f /v "{E0A941A0-88A2-4df5-8D6B-DD20BB06E8FB},4" /t REG_DWORD /d "1"
net stop audiosrv //just restarting audio down here , not important
net stop AudioEndpointBuilder
net start audiosrv
net start AudioEndpointBuilder
pause

批处理文件执行后 Windows 注册表中的值已从 0 更改为 1(所需操作)。

因此,当我直接从命令提示符 window 运行 命令时,我可以看到值已更改。但是当我 运行 我的命令从 运行time exec 在我的 Java 应用程序中时, Windows 注册表中的值没有改变,尽管我看到命令执行没有问题。在我的 Java 调试中,我看到正在执行的命令与我在批处理文件中执行的命令完全相同。

在我的 Java 应用程序中执行的 reg.exe 命令未更改注册表值的原因可能是什么?

进程监视器屏幕(Mofi 提示后):

WOW6432NodeProcess Monitor 的日志中表示 Java 代码是用 32 位 Java 在 32- 64 位 Windows 上的位环境。因此被调用的 reg.exe 也是 32 位的 %SystemRoot%\SysWOW64\reg.exe 从而修改 WOW6432Node.

中的 DWORD 值

有关 Windows 的详细信息的 Microsoft 文章 Windows:

在 32 位和 64 位 Windows 上适用于 32 位和 64 位 Java 的一个解决方案是:

  1. 获取环境变量SystemRoot的字符串值。

  2. 检查文件 SystemRoot + "\Sysnative\reg.exe" 是否存在。

    这只是在 64 位 Windows 上执行的 32 位 Java 的情况。在所有其他情况下,即 64 位 Java 在 64 位 Windows 上或 32 位 Java 在 32 位 Windows 上,此文件不存在,因为 Sysnative 不存在。是的,64 位 Windows.

    上的 64 位应用程序不存在 Sysnative
  3. 如果文件reg.exe存在于Windows目录的Sysnative中,调用SystemRoot + "\Sysnative\reg.exe".

  4. 否则调用 SystemRoot + "\System32\reg.exe" 这是 64 位 Java 在 64 位 Windows 和 32 位 Java 上的正确可执行文件] 在 32 位 Windows.