使用 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 提示后):
WOW6432Node
在 Process Monitor 的日志中表示 Java 代码是用 32 位 Java 在 32- 64 位 Windows 上的位环境。因此被调用的 reg.exe
也是 32 位的 %SystemRoot%\SysWOW64\reg.exe
从而修改 WOW6432Node
.
中的 DWORD 值
有关 Windows 的详细信息的 Microsoft 文章 Windows:
- File System Redirector
- Registry Redirector
- Registry Keys Affected by WOW64
- WOW64 Implementation Details
在 32 位和 64 位 Windows 上适用于 32 位和 64 位 Java 的一个解决方案是:
获取环境变量SystemRoot
的字符串值。
检查文件 SystemRoot + "\Sysnative\reg.exe"
是否存在。
这只是在 64 位 Windows 上执行的 32 位 Java 的情况。在所有其他情况下,即 64 位 Java 在 64 位 Windows 上或 32 位 Java 在 32 位 Windows 上,此文件不存在,因为 Sysnative
不存在。是的,64 位 Windows.
上的 64 位应用程序不存在 Sysnative
如果文件reg.exe
存在于Windows目录的Sysnative
中,调用SystemRoot + "\Sysnative\reg.exe"
.
否则调用 SystemRoot + "\System32\reg.exe"
这是 64 位 Java 在 64 位 Windows 和 32 位 Java 上的正确可执行文件] 在 32 位 Windows.
我正在尝试从我的 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 提示后):
WOW6432Node
在 Process Monitor 的日志中表示 Java 代码是用 32 位 Java 在 32- 64 位 Windows 上的位环境。因此被调用的 reg.exe
也是 32 位的 %SystemRoot%\SysWOW64\reg.exe
从而修改 WOW6432Node
.
有关 Windows 的详细信息的 Microsoft 文章 Windows:
- File System Redirector
- Registry Redirector
- Registry Keys Affected by WOW64
- WOW64 Implementation Details
在 32 位和 64 位 Windows 上适用于 32 位和 64 位 Java 的一个解决方案是:
获取环境变量
SystemRoot
的字符串值。检查文件
SystemRoot + "\Sysnative\reg.exe"
是否存在。这只是在 64 位 Windows 上执行的 32 位 Java 的情况。在所有其他情况下,即 64 位 Java 在 64 位 Windows 上或 32 位 Java 在 32 位 Windows 上,此文件不存在,因为
上的 64 位应用程序不存在Sysnative
不存在。是的,64 位 Windows.Sysnative
如果文件
reg.exe
存在于Windows目录的Sysnative
中,调用SystemRoot + "\Sysnative\reg.exe"
.否则调用
SystemRoot + "\System32\reg.exe"
这是 64 位 Java 在 64 位 Windows 和 32 位 Java 上的正确可执行文件] 在 32 位 Windows.