问题
I'm trying to change registry value from my Java application. I use the command:
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 function:
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);
}
}
Everything works okay. I get output into command prompt:
The operation completed successfully
So I start regedit to verify if value has changed, but to my surprise nothing changed. The value is the same as before.
Do I have permissions? Yes
I use a batch file to execute my application with Run as administrator.
Batch file:
cd %~dp0
java -jar LoudnessEqualizationToggle.jar
pause
Created shortcut from that and run as administrator.
Are you owner of that key? Yes
I tested my command and permissions with a batch file testing if the current value 0
in Windows registry can be changed to 1
as expected.
Batch file for that test is:
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
The value has changed in Windows registry after batch file execution from 0 to 1 (desired action).
So when I run my command from command prompt window directly, I can see the value changed. But when I run my command from runtime exec within my Java application, no value is changed in Windows registry, although I see that the command executed with no problem. And on my Java debug I see EXACTLY the same command being executed as I have in batch file.
What could be the reason for not getting the registry value changed by reg.exe command executed from within my Java application?
Process Monitor screen (after a tip by Mofi):
回答1:
WOW6432Node
in Process Monitor log indicates that the Java code is executed with 32-bit Java in a 32-bit environment on Windows x64. Therefore the called reg.exe
is also the 32-bit %SystemRoot%\SysWOW64\reg.exe
which modifies therefore the DWORD value in WOW6432Node
.
Microsoft articles with details about Windows On Windows:
- File System Redirector
- Registry Redirector
- Registry Keys Affected by WOW64
- WOW64 Implementation Details
One solution working for 32-bit and 64-bit Java on 32-bit and 64-bit Windows would be:
Get string value of environment variable
SystemRoot
.Check if file
SystemRoot + "\\Sysnative\\reg.exe"
exists.This is only the case for 32-bit Java executed on Windows x64. In all other cases, i.e. 64-bit Java on Windows x64 or 32-bit Java on Windows x86, this file does not exist because
Sysnative
does not exist. Yes,Sysnative
does not exist for 64-bit applications on Windows x64.If the file
reg.exe
exists inSysnative
in Windows directory, callSystemRoot + "\\Sysnative\\reg.exe"
.Otherwise call
SystemRoot + "\\System32\\reg.exe"
which is the right executable for 64-bit Java on Windows x64 as well as 32-bit Java on Windows x86.
来源:https://stackoverflow.com/questions/36821832/changing-value-of-registry-key-with-getruntime-execcmd-does-not-change-regis