使用getRuntime().exe(cmd)更改registry项的值不会更改registry值,即使操作已成功结束

我试图从我的Java应用程序更改registry值。 我使用这个命令:

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)+"\""); 

凡guid是{d348b8e8-3118-4a9c-9b43-422647b555ca}

activateLEOnKey是布尔值

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); } } 

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

操作成功完成

所以我开始注册,以validation价值是否已经改变,但我感到惊讶没有任何改变。 价值是一样的以前。

我有权限吗?
我使用batch file以pipe理员身份运行我的应用程序。

batch file:

 cd %~dp0 java -jar LoudnessEqualizationToggle.jar pause 

创build的快捷方式,并以pipe理员身份运行。

你是那个钥匙的主人吗?

我使用batch filetesting了我的命令和权限,如果Windowsregistry中的当前值0可以按预期更改为1

该testing的batch file是:

 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 

batch file执行后,Windowsregistry中的值已从0更改为1(所需的操作)。

所以当我直接从命令提示符窗口运行我的命令,我可以看到值改变。 但是,当我在我的Java应用程序中运行我的命令从运行时执行,在Windowsregistry中没有任何值更改,虽然我看到命令执行没有问题。 而在我的Javadebugging,我看到完全相同的命令正在执行,因为我有batch file。

什么可能是没有得到由我的Java应用程序内执行reg.exe命令更改registry值的原因?

过程监视器屏幕(在由Mofi提示之后):

进程监视器日志与过滤器设置为包括路径中的MMDevices的所有注册表访问

Solutions Collecting From Web of "使用getRuntime().exe(cmd)更改registry项的值不会更改registry值,即使操作已成功结束"

进程监视器日志中的WOW6432Node表示Java代码是在Windows x64的32位环境中使用32位Java执行的。 因此,被调用的reg.exe也是32位%SystemRoot%\SysWOW64\reg.exe ,因此修改了WOW6432Node的DWORD值。

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

  • 文件系统重定向器
  • 注册表重定向器
  • 受WOW64影响的注册表键
  • WOW64实现细节

在32位和64位Windows上运行32位和64位Java的一种解决方案是:

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

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

    对于在Windows x64上执行的32位Java只有这种情况。 在所有其他情况下,即Windows x64上的64位Java或Windows x86上的32位Java,此文件不存在,因为Sysnative不存在。 是的,对于Windows x64上的64位应用程序, Sysnative不存在。

  3. 如果在Windows目录中的Sysnative中存在reg.exe文件,请调用SystemRoot + "\\Sysnative\\reg.exe"

  4. 否则,请调用SystemRoot + "\\System32\\reg.exe" ,这是Windows x64上的64位Java以及Windows x86上的32位Java的正确可执行文件。