feat: add in selectbox in Java settings tab to Java paths on windows
This commit is contained in:
parent
71976f00b6
commit
a33fc95ca7
10 changed files with 632 additions and 10 deletions
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -1,3 +1 @@
|
|||
{
|
||||
"java.home": "C:\\Program Files\\Amazon Corretto\\jdk11.0.3_7"
|
||||
}
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
- Fix issue with installing Fabric not downloading all libraries needed
|
||||
- Add ability to select loader versions for packs that enable it
|
||||
- Add ability to add mods from within the launcher direct from Curse
|
||||
- Add in selectbox in Java settings tab to Java paths on windows
|
||||
|
|
|
@ -64,6 +64,7 @@ license {
|
|||
exclude 'de/zh32/**/*.java'
|
||||
exclude 'io/github/**/*.java'
|
||||
exclude 'net/minecraft/**/*.java'
|
||||
exclude 'com/atlauncher/utils/javafinder/*.java'
|
||||
newLine = false
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -65,6 +66,8 @@ import com.atlauncher.utils.HTMLUtils;
|
|||
import com.atlauncher.utils.Java;
|
||||
import com.atlauncher.utils.OS;
|
||||
import com.atlauncher.utils.Utils;
|
||||
import com.atlauncher.utils.javafinder.JavaFinder;
|
||||
import com.atlauncher.utils.javafinder.JavaInfo;
|
||||
|
||||
import io.github.asyncronous.toast.Toaster;
|
||||
import joptsimple.OptionParser;
|
||||
|
|
|
@ -17,10 +17,12 @@
|
|||
*/
|
||||
package com.atlauncher.gui.tabs.settings;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
|
@ -38,8 +40,10 @@ import com.atlauncher.evnt.listener.RelocalizationListener;
|
|||
import com.atlauncher.evnt.manager.RelocalizationManager;
|
||||
import com.atlauncher.gui.components.JLabelWithHover;
|
||||
import com.atlauncher.managers.DialogManager;
|
||||
import com.atlauncher.utils.Java;
|
||||
import com.atlauncher.utils.OS;
|
||||
import com.atlauncher.utils.Utils;
|
||||
import com.atlauncher.utils.javafinder.JavaInfo;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class JavaSettingsTab extends AbstractSettingsTab implements RelocalizationListener {
|
||||
|
@ -230,8 +234,36 @@ public class JavaSettingsTab extends AbstractSettingsTab implements Relocalizati
|
|||
gbc.gridx++;
|
||||
gbc.insets = LABEL_INSETS_SMALL;
|
||||
gbc.anchor = GridBagConstraints.BASELINE_LEADING;
|
||||
javaPathPanel = new JPanel();
|
||||
javaPathPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
javaPathPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel javaPathPanelTop = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
JPanel javaPathPanelBottom = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
|
||||
if (OS.isWindows()) {
|
||||
JComboBox<JavaInfo> installedJavas = new JComboBox<>();
|
||||
List<JavaInfo> systemJavas = Java.getInstalledJavas();
|
||||
|
||||
systemJavas.stream().forEach(javaInfo -> {
|
||||
installedJavas.addItem(javaInfo);
|
||||
});
|
||||
|
||||
installedJavas
|
||||
.setSelectedItem(systemJavas.stream()
|
||||
.filter(javaInfo -> javaInfo.path
|
||||
.replace(OS.osSlash() + "bin" + OS.osSlash() + "java.exe", "")
|
||||
.equalsIgnoreCase(App.settings.getJavaPath()))
|
||||
.findFirst().get());
|
||||
|
||||
installedJavas.addActionListener(e -> {
|
||||
javaPath.setText(((JavaInfo) installedJavas.getSelectedItem()).path
|
||||
.replace(OS.osSlash() + "bin" + OS.osSlash() + "java.exe", ""));
|
||||
});
|
||||
|
||||
if (installedJavas.getItemCount() != 0) {
|
||||
javaPathPanelTop.add(installedJavas);
|
||||
}
|
||||
}
|
||||
|
||||
javaPath = new JTextField(32);
|
||||
javaPath.setText(App.settings.getJavaPath());
|
||||
javaPathResetButton = new JButton(Language.INSTANCE.localize("settings.javapathreset"));
|
||||
|
@ -248,9 +280,11 @@ public class JavaSettingsTab extends AbstractSettingsTab implements Relocalizati
|
|||
javaPath.setText(chooser.getSelectedFile().getAbsolutePath());
|
||||
}
|
||||
});
|
||||
javaPathPanel.add(javaPath);
|
||||
javaPathPanel.add(javaPathResetButton);
|
||||
javaPathPanel.add(javaBrowseButton);
|
||||
javaPathPanelBottom.add(javaPath);
|
||||
javaPathPanelBottom.add(javaPathResetButton);
|
||||
javaPathPanelBottom.add(javaBrowseButton);
|
||||
javaPathPanel.add(javaPathPanelTop, BorderLayout.NORTH);
|
||||
javaPathPanel.add(javaPathPanelBottom, BorderLayout.CENTER);
|
||||
add(javaPathPanel, gbc);
|
||||
|
||||
// Java Paramaters
|
||||
|
|
|
@ -21,11 +21,14 @@ import java.io.BufferedReader;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.atlauncher.App;
|
||||
import com.atlauncher.LogManager;
|
||||
import com.atlauncher.utils.javafinder.JavaFinder;
|
||||
import com.atlauncher.utils.javafinder.JavaInfo;
|
||||
|
||||
public class Java {
|
||||
/**
|
||||
|
@ -76,8 +79,8 @@ public class Java {
|
|||
}
|
||||
|
||||
if (version.equals("Unknown")) {
|
||||
LogManager.warn("Cannot get Java version from the output of \""
|
||||
+ getPathToSystemJavaExecutable() + " -version\"");
|
||||
LogManager.warn("Cannot get Java version from the output of \"" + getPathToSystemJavaExecutable()
|
||||
+ " -version\"");
|
||||
}
|
||||
|
||||
return version;
|
||||
|
@ -221,4 +224,8 @@ public class Java {
|
|||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static List<JavaInfo> getInstalledJavas() {
|
||||
return JavaFinder.findJavas();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License.
|
||||
* Needs WinRegistry.java. Get it at: https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
|
||||
*
|
||||
* JavaFinder - Windows-specific classes to search for all installed versions of java on this system
|
||||
* Author: petrucio@stackoverflow (828681)
|
||||
*/
|
||||
package com.atlauncher.utils.javafinder;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaFinder {
|
||||
/**
|
||||
* @return: A list of javaExec paths found under this registry key (rooted at
|
||||
* HKEY_LOCAL_MACHINE)
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app,
|
||||
* 64-bits for 64-bits app) or WinRegistry.KEY_WOW64_32KEY to
|
||||
* force access to 32-bit registry view, or
|
||||
* WinRegistry.KEY_WOW64_64KEY to force access to 64-bit
|
||||
* registry view
|
||||
* @param previous: Insert all entries from this list at the beggining of the
|
||||
* results
|
||||
*************************************************************************/
|
||||
private static List<String> searchRegistry(String key, int wow64, List<String> previous) {
|
||||
List<String> result = previous;
|
||||
try {
|
||||
List<String> entries = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, key, wow64);
|
||||
for (int i = 0; entries != null && i < entries.size(); i++) {
|
||||
String val = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, key + "\\" + entries.get(i),
|
||||
"JavaHome", wow64);
|
||||
if (!result.contains(val + "\\bin\\java.exe")) {
|
||||
result.add(val + "\\bin\\java.exe");
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return: A list of JavaInfo with informations about all javas installed on
|
||||
* this machine Searches and returns results in this order:
|
||||
* HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
|
||||
* (32-bits view) HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime
|
||||
* Environment (64-bits view) HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java
|
||||
* Development Kit (32-bits view)
|
||||
* HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit (64-bits
|
||||
* view) WINDIR\system32 WINDIR\SysWOW64
|
||||
****************************************************************************/
|
||||
public static List<JavaInfo> findJavas() {
|
||||
List<String> javaExecs = new ArrayList<String>();
|
||||
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment",
|
||||
WinRegistry.KEY_WOW64_32KEY, javaExecs);
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment",
|
||||
WinRegistry.KEY_WOW64_64KEY, javaExecs);
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit", WinRegistry.KEY_WOW64_32KEY,
|
||||
javaExecs);
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit", WinRegistry.KEY_WOW64_64KEY,
|
||||
javaExecs);
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\JDK", WinRegistry.KEY_WOW64_32KEY, javaExecs);
|
||||
javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\JDK", WinRegistry.KEY_WOW64_64KEY, javaExecs);
|
||||
|
||||
javaExecs.add(System.getenv("WINDIR") + "\\system32\\java.exe");
|
||||
javaExecs.add(System.getenv("WINDIR") + "\\SysWOW64\\java.exe");
|
||||
|
||||
List<JavaInfo> result = new ArrayList<JavaInfo>();
|
||||
for (String javaPath : javaExecs) {
|
||||
if (!(new File(javaPath).exists()))
|
||||
continue;
|
||||
result.add(new JavaInfo(javaPath));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return: The path to a java.exe that has the same bitness as the OS (or null
|
||||
* if no matching java is found)
|
||||
****************************************************************************/
|
||||
public static String getOSBitnessJava() {
|
||||
String arch = System.getenv("PROCESSOR_ARCHITECTURE");
|
||||
String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
|
||||
boolean isOS64 = arch.endsWith("64") || (wow64Arch != null && wow64Arch.endsWith("64"));
|
||||
|
||||
List<JavaInfo> javas = JavaFinder.findJavas();
|
||||
for (int i = 0; i < javas.size(); i++) {
|
||||
if (javas.get(i).is64bits == isOS64)
|
||||
return javas.get(i).path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
48
src/main/java/com/atlauncher/utils/javafinder/JavaInfo.java
Normal file
48
src/main/java/com/atlauncher/utils/javafinder/JavaInfo.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License.
|
||||
* Needs WinRegistry.java. Get it at: https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
|
||||
*
|
||||
* JavaFinder - Windows-specific classes to search for all installed versions of java on this system
|
||||
* Author: petrucio@stackoverflow (828681)
|
||||
*/
|
||||
package com.atlauncher.utils.javafinder;
|
||||
|
||||
import com.atlauncher.utils.Java;
|
||||
|
||||
/**
|
||||
* Helper struct to hold information about one installed java version
|
||||
****************************************************************************/
|
||||
public class JavaInfo {
|
||||
public String path; // ! Full path to java.exe executable file
|
||||
public String version; // ! Version string. "Unkown" if the java process returned non-standard version
|
||||
// string
|
||||
public Integer majorVersion; // The major version
|
||||
public boolean is64bits; // ! true for 64-bit javas, false for 32
|
||||
|
||||
/**
|
||||
* Calls 'javaPath -version' and parses the results
|
||||
*
|
||||
* @param javaPath: path to a java.exe executable
|
||||
****************************************************************************/
|
||||
public JavaInfo(String javaPath) {
|
||||
String versionInfo = RuntimeStreamer.execute(new String[] { javaPath, "-version" });
|
||||
String[] tokens = versionInfo.split("\"");
|
||||
|
||||
if (tokens.length < 2) {
|
||||
this.version = "Unkown";
|
||||
} else {
|
||||
this.version = tokens[1];
|
||||
this.majorVersion = Java.parseJavaVersionNumber(this.version);
|
||||
}
|
||||
|
||||
this.is64bits = versionInfo.toUpperCase().contains("64-BIT");
|
||||
this.path = javaPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Human-readable contents of this JavaInfo instance
|
||||
****************************************************************************/
|
||||
public String toString() {
|
||||
return this.path + " (" + (this.is64bits ? "64-bit" : "32-bit") + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License.
|
||||
* Needs WinRegistry.java. Get it at: https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
|
||||
*
|
||||
* JavaFinder - Windows-specific classes to search for all installed versions of java on this system
|
||||
* Author: petrucio@stackoverflow (828681)
|
||||
*/
|
||||
package com.atlauncher.utils.javafinder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* Helper class to fetch the stdout and stderr outputs from started Runtime
|
||||
* execs Modified from
|
||||
* http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
|
||||
*****************************************************************************/
|
||||
public class RuntimeStreamer extends Thread {
|
||||
InputStream is;
|
||||
String lines;
|
||||
|
||||
RuntimeStreamer(InputStream is) {
|
||||
this.is = is;
|
||||
this.lines = "";
|
||||
}
|
||||
|
||||
public String contents() {
|
||||
return this.lines;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
this.lines += line + "\n";
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command and wait for it to finish
|
||||
*
|
||||
* @return The resulting stdout and stderr outputs concatenated
|
||||
****************************************************************************/
|
||||
public static String execute(String[] cmdArray) {
|
||||
try {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Process proc = runtime.exec(cmdArray);
|
||||
RuntimeStreamer outputStreamer = new RuntimeStreamer(proc.getInputStream());
|
||||
RuntimeStreamer errorStreamer = new RuntimeStreamer(proc.getErrorStream());
|
||||
outputStreamer.start();
|
||||
errorStreamer.start();
|
||||
proc.waitFor();
|
||||
return outputStreamer.contents() + errorStreamer.contents();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String execute(String cmd) {
|
||||
String[] cmdArray = { cmd };
|
||||
return RuntimeStreamer.execute(cmdArray);
|
||||
}
|
||||
}
|
364
src/main/java/com/atlauncher/utils/javafinder/WinRegistry.java
Normal file
364
src/main/java/com/atlauncher/utils/javafinder/WinRegistry.java
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Pure Java Windows Registry access.
|
||||
* Modified by petrucio@stackoverflow(828681) to add support for
|
||||
* reading (and writing but not creating/deleting keys) the 32-bits
|
||||
* registry view from a 64-bits JVM (KEY_WOW64_32KEY)
|
||||
* and 64-bits view from a 32-bits JVM (KEY_WOW64_64KEY).
|
||||
*/
|
||||
package com.atlauncher.utils.javafinder;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class WinRegistry {
|
||||
public static final int HKEY_CURRENT_USER = 0x80000001;
|
||||
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
|
||||
public static final int REG_SUCCESS = 0;
|
||||
public static final int REG_NOTFOUND = 2;
|
||||
public static final int REG_ACCESSDENIED = 5;
|
||||
|
||||
public static final int KEY_WOW64_32KEY = 0x0200;
|
||||
public static final int KEY_WOW64_64KEY = 0x0100;
|
||||
|
||||
private static final int KEY_ALL_ACCESS = 0xf003f;
|
||||
private static final int KEY_READ = 0x20019;
|
||||
private static Preferences userRoot = Preferences.userRoot();
|
||||
private static Preferences systemRoot = Preferences.systemRoot();
|
||||
private static Class<? extends Preferences> userClass = userRoot.getClass();
|
||||
private static Method regOpenKey = null;
|
||||
private static Method regCloseKey = null;
|
||||
private static Method regQueryValueEx = null;
|
||||
private static Method regEnumValue = null;
|
||||
private static Method regQueryInfoKey = null;
|
||||
private static Method regEnumKeyEx = null;
|
||||
private static Method regCreateKeyEx = null;
|
||||
private static Method regSetValueEx = null;
|
||||
private static Method regDeleteKey = null;
|
||||
private static Method regDeleteValue = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
|
||||
new Class[] { int.class, byte[].class, int.class });
|
||||
regOpenKey.setAccessible(true);
|
||||
regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", new Class[] { int.class });
|
||||
regCloseKey.setAccessible(true);
|
||||
regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
|
||||
new Class[] { int.class, byte[].class });
|
||||
regQueryValueEx.setAccessible(true);
|
||||
regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
|
||||
new Class[] { int.class, int.class, int.class });
|
||||
regEnumValue.setAccessible(true);
|
||||
regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1", new Class[] { int.class });
|
||||
regQueryInfoKey.setAccessible(true);
|
||||
regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx",
|
||||
new Class[] { int.class, int.class, int.class });
|
||||
regEnumKeyEx.setAccessible(true);
|
||||
regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx",
|
||||
new Class[] { int.class, byte[].class });
|
||||
regCreateKeyEx.setAccessible(true);
|
||||
regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx",
|
||||
new Class[] { int.class, byte[].class, byte[].class });
|
||||
regSetValueEx.setAccessible(true);
|
||||
regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue",
|
||||
new Class[] { int.class, byte[].class });
|
||||
regDeleteValue.setAccessible(true);
|
||||
regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[] { int.class, byte[].class });
|
||||
regDeleteKey.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private WinRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a value from key and value name
|
||||
*
|
||||
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
||||
* @param key
|
||||
* @param valueName
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app,
|
||||
* 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access
|
||||
* to 32-bit registry view, or KEY_WOW64_64KEY to force access
|
||||
* to 64-bit registry view
|
||||
* @return the value
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static String readString(int hkey, String key, String valueName, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
return readString(systemRoot, hkey, key, valueName, wow64);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
return readString(userRoot, hkey, key, valueName, wow64);
|
||||
} else {
|
||||
throw new IllegalArgumentException("hkey=" + hkey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read value(s) and value name(s) form given key
|
||||
*
|
||||
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
||||
* @param key
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app, 64-bits
|
||||
* for 64-bits app) or KEY_WOW64_32KEY to force access to 32-bit
|
||||
* registry view, or KEY_WOW64_64KEY to force access to 64-bit
|
||||
* registry view
|
||||
* @return the value name(s) plus the value(s)
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static Map<String, String> readStringValues(int hkey, String key, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
return readStringValues(systemRoot, hkey, key, wow64);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
return readStringValues(userRoot, hkey, key, wow64);
|
||||
} else {
|
||||
throw new IllegalArgumentException("hkey=" + hkey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value name(s) from a given key
|
||||
*
|
||||
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
||||
* @param key
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app, 64-bits
|
||||
* for 64-bits app) or KEY_WOW64_32KEY to force access to 32-bit
|
||||
* registry view, or KEY_WOW64_64KEY to force access to 64-bit
|
||||
* registry view
|
||||
* @return the value name(s)
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static List<String> readStringSubKeys(int hkey, String key, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
return readStringSubKeys(systemRoot, hkey, key, wow64);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
return readStringSubKeys(userRoot, hkey, key, wow64);
|
||||
} else {
|
||||
throw new IllegalArgumentException("hkey=" + hkey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a key
|
||||
*
|
||||
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
||||
* @param key
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static void createKey(int hkey, String key)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int[] ret;
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
ret = createKey(systemRoot, hkey, key);
|
||||
regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
ret = createKey(userRoot, hkey, key);
|
||||
regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
|
||||
} else {
|
||||
throw new IllegalArgumentException("hkey=" + hkey);
|
||||
}
|
||||
if (ret[1] != REG_SUCCESS) {
|
||||
throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a value in a given key/value name
|
||||
*
|
||||
* @param hkey
|
||||
* @param key
|
||||
* @param valueName
|
||||
* @param value
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app,
|
||||
* 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access
|
||||
* to 32-bit registry view, or KEY_WOW64_64KEY to force access
|
||||
* to 64-bit registry view
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static void writeStringValue(int hkey, String key, String valueName, String value, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
writeStringValue(systemRoot, hkey, key, valueName, value, wow64);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
writeStringValue(userRoot, hkey, key, valueName, value, wow64);
|
||||
} else {
|
||||
throw new IllegalArgumentException("hkey=" + hkey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a given key
|
||||
*
|
||||
* @param hkey
|
||||
* @param key
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static void deleteKey(int hkey, String key)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int rc = -1;
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
rc = deleteKey(systemRoot, hkey, key);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
rc = deleteKey(userRoot, hkey, key);
|
||||
}
|
||||
if (rc != REG_SUCCESS) {
|
||||
throw new IllegalArgumentException("rc=" + rc + " key=" + key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a value from a given key/value name
|
||||
*
|
||||
* @param hkey
|
||||
* @param key
|
||||
* @param value
|
||||
* @param wow64 0 for standard registry access (32-bits for 32-bit app, 64-bits
|
||||
* for 64-bits app) or KEY_WOW64_32KEY to force access to 32-bit
|
||||
* registry view, or KEY_WOW64_64KEY to force access to 64-bit
|
||||
* registry view
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public static void deleteValue(int hkey, String key, String value, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int rc = -1;
|
||||
if (hkey == HKEY_LOCAL_MACHINE) {
|
||||
rc = deleteValue(systemRoot, hkey, key, value, wow64);
|
||||
} else if (hkey == HKEY_CURRENT_USER) {
|
||||
rc = deleteValue(userRoot, hkey, key, value, wow64);
|
||||
}
|
||||
if (rc != REG_SUCCESS) {
|
||||
throw new IllegalArgumentException("rc=" + rc + " key=" + key + " value=" + value);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static int deleteValue(Preferences root, int hkey, String key, String value, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int[] handles = (int[]) regOpenKey.invoke(root,
|
||||
new Object[] { new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS | wow64) });
|
||||
if (handles[1] != REG_SUCCESS) {
|
||||
return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
|
||||
}
|
||||
int rc = ((Integer) regDeleteValue.invoke(root, new Object[] { new Integer(handles[0]), toCstr(value) }))
|
||||
.intValue();
|
||||
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static int deleteKey(Preferences root, int hkey, String key)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int rc = ((Integer) regDeleteKey.invoke(root, new Object[] { new Integer(hkey), toCstr(key) })).intValue();
|
||||
return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static String readString(Preferences root, int hkey, String key, String value, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int[] handles = (int[]) regOpenKey.invoke(root,
|
||||
new Object[] { new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64) });
|
||||
if (handles[1] != REG_SUCCESS) {
|
||||
return null;
|
||||
}
|
||||
byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] { new Integer(handles[0]), toCstr(value) });
|
||||
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
return (valb != null ? new String(valb).trim() : null);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static Map<String, String> readStringValues(Preferences root, int hkey, String key, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
HashMap<String, String> results = new HashMap<String, String>();
|
||||
int[] handles = (int[]) regOpenKey.invoke(root,
|
||||
new Object[] { new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64) });
|
||||
if (handles[1] != REG_SUCCESS) {
|
||||
return null;
|
||||
}
|
||||
int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
|
||||
int count = info[2]; // count
|
||||
int maxlen = info[3]; // value length max
|
||||
for (int index = 0; index < count; index++) {
|
||||
byte[] name = (byte[]) regEnumValue.invoke(root,
|
||||
new Object[] { new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1) });
|
||||
String value = readString(hkey, key, new String(name), wow64);
|
||||
results.put(new String(name).trim(), value);
|
||||
}
|
||||
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
return results;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static List<String> readStringSubKeys(Preferences root, int hkey, String key, int wow64)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
List<String> results = new ArrayList<String>();
|
||||
int[] handles = (int[]) regOpenKey.invoke(root,
|
||||
new Object[] { new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64) });
|
||||
if (handles[1] != REG_SUCCESS) {
|
||||
return null;
|
||||
}
|
||||
int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
|
||||
int count = info[0]; // Fix: info[2] was being used here with wrong results. Suggested by davenpcj,
|
||||
// confirmed by Petrucio
|
||||
int maxlen = info[3]; // value length max
|
||||
for (int index = 0; index < count; index++) {
|
||||
byte[] name = (byte[]) regEnumKeyEx.invoke(root,
|
||||
new Object[] { new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1) });
|
||||
results.add(new String(name).trim());
|
||||
}
|
||||
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
return results;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static int[] createKey(Preferences root, int hkey, String key)
|
||||
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
return (int[]) regCreateKeyEx.invoke(root, new Object[] { new Integer(hkey), toCstr(key) });
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value,
|
||||
int wow64) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
int[] handles = (int[]) regOpenKey.invoke(root,
|
||||
new Object[] { new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS | wow64) });
|
||||
regSetValueEx.invoke(root, new Object[] { new Integer(handles[0]), toCstr(valueName), toCstr(value) });
|
||||
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// utility
|
||||
private static byte[] toCstr(String str) {
|
||||
byte[] result = new byte[str.length() + 1];
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
result[i] = (byte) str.charAt(i);
|
||||
}
|
||||
result[str.length()] = 0;
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue