Javaを使ってWindowsレジストリを読み書きするにはどうすればよいですか。
私はこの質問が古いことを知っています、しかしそれはグーグル上で "レジストリに読み書きするJava"への最初の検索結果です。最近、私はこの驚くべきコードを見つけました。
これは純粋なJavaコードです。
実際にはJava.util.prefs.Preferences
クラスのprivateメソッドにアクセスすることでリフレクションを使用しています。このクラスの内部は複雑ですが、クラス自体は非常に使いやすいです。
たとえば、次のコードは正確なウィンドウ分布を取得しますレジストリから:
String value = WinRegistry.readString (
WinRegistry.HKEY_LOCAL_MACHINE, //HKEY
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", //Key
"ProductName"); //ValueName
System.out.println("Windows Distribution = " + value);
これが元のクラスです。コピーして貼り付けるだけでうまくいきます。
import Java.lang.reflect.InvocationTargetException;
import Java.lang.reflect.Method;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.ArrayList;
import Java.util.List;
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;
private static final int KEY_ALL_ACCESS = 0xf003f;
private static final int KEY_READ = 0x20019;
private static final Preferences userRoot = Preferences.userRoot();
private static final Preferences systemRoot = Preferences.systemRoot();
private static final Class<? extends Preferences> userClass = userRoot.getClass();
private static final Method regOpenKey;
private static final Method regCloseKey;
private static final Method regQueryValueEx;
private static final Method regEnumValue;
private static final Method regQueryInfoKey;
private static final Method regEnumKeyEx;
private static final Method regCreateKeyEx;
private static final Method regSetValueEx;
private static final Method regDeleteKey;
private static final Method regDeleteValue;
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) {
throw new RuntimeException(e);
}
}
private WinRegistry() { }
/**
* Read a value from key and value name
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @param valueName
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static String readString(int hkey, String key, String valueName)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readString(systemRoot, hkey, key, valueName);
}
else if (hkey == HKEY_CURRENT_USER) {
return readString(userRoot, hkey, key, valueName);
}
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
* @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)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringValues(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringValues(userRoot, hkey, key);
}
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
* @return the value name(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> readStringSubKeys(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringSubKeys(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringSubKeys(userRoot, hkey, key);
}
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
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue
(int hkey, String key, String valueName, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
if (hkey == HKEY_LOCAL_MACHINE) {
writeStringValue(systemRoot, hkey, key, valueName, value);
}
else if (hkey == HKEY_CURRENT_USER) {
writeStringValue(userRoot, hkey, key, valueName, value);
}
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
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteValue(systemRoot, hkey, key, value);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteValue(userRoot, hkey, key, value);
}
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)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
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)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
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)
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) });
if (handles[1] != REG_SUCCESS) {
return null;
}
int[] info = (int[]) regQueryInfoKey.invoke(root,
new Object[] { new Integer(handles[0]) });
int count = info[0]; // 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));
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)
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)
});
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)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
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;
}
}
このコードの原作者を見つけて信用することができませんでした。詳細を見つけた場合は、コメントを追加してください。ここに追加します。
あなたは実際にサードパーティのパッケージを必要としません。 Windowsにはすべてのレジストリ操作用のregユーティリティがあります。コマンドフォーマットを取得するには、DOSコマンドに移動して次のように入力します。
reg /?
Runtimeクラスを通じてregを呼び出すことができます。
Runtime.getRuntime().exec("reg <your parameters here>");
上記のコマンドを使用してキーを編集して新しいキーを追加するのは簡単です。レジストリを読むために、あなたはregの出力を得る必要があります、そしてそれは少しトリッキーです。これがコードです:
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.StringWriter;
/**
* @author Oleg Ryaboy, based on work by Miguel Enriquez
*/
public class WindowsReqistry {
/**
*
* @param location path in the registry
* @param key registry key
* @return registry value or null if not found
*/
public static final String readRegistry(String location, String key){
try {
// Run reg query, then read output with StreamReader (internal class)
Process process = Runtime.getRuntime().exec("reg query " +
'"'+ location + "\" /v " + key);
StreamReader reader = new StreamReader(process.getInputStream());
reader.start();
process.waitFor();
reader.join();
String output = reader.getResult();
// Output has the following format:
// \n<Version information>\n\n<key>\t<registry type>\t<value>
if( ! output.contains("\t")){
return null;
}
// Parse out the value
String[] parsed = output.split("\t");
return parsed[parsed.length-1];
}
catch (Exception e) {
return null;
}
}
static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw= new StringWriter();
public StreamReader(InputStream is) {
this.is = is;
}
public void run() {
try {
int c;
while ((c = is.read()) != -1)
sw.write(c);
}
catch (IOException e) {
}
}
public String getResult() {
return sw.toString();
}
}
public static void main(String[] args) {
// Sample usage
String value = WindowsReqistry.readRegistry("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\"
+ "Explorer\\Shell Folders", "Personal");
System.out.println(value);
}
}
Java Native Access(JNA) はネイティブライブラリを操作するための優れたプロジェクトで、プラットフォームライブラリ(platform.jar)から Advapi32Util そして - のWindowsレジストリをサポートしています。 Advapi32 .
更新:JNAを使用してJNA 3.4.1を使用してWindowsレジストリを操作するのが簡単な例をいくつか示します。
import com.Sun.jna.platform.win32.Advapi32Util;
import com.Sun.jna.platform.win32.WinReg;
public class WindowsRegistrySnippet {
public static void main(String[] args) {
// Read a string
String productName = Advapi32Util.registryGetStringValue(
WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
System.out.printf("Product Name: %s\n", productName);
// Read an int (& 0xFFFFFFFFL for large unsigned int)
int timeout = Advapi32Util.registryGetIntValue(
WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", "ShutdownWarningDialogTimeout");
System.out.printf("Shutdown Warning Dialog Timeout: %d (%d as unsigned long)\n", timeout, timeout & 0xFFFFFFFFL);
// Create a key and write a string
Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow");
Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow", "url", "http://stackoverflow.com/a/6287763/277307");
// Delete a key
Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow");
}
}
私はもともとDavidによって投稿されたPure Javaコードをインクリメントして、64ビットJVMからレジストリの32ビットセクションにアクセスできるようにしました。私は他の答えのどれもこれに対処するとは思わない。
ここにあります:
/**
* 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).
*****************************************************************************/
import Java.lang.reflect.InvocationTargetException;
import Java.lang.reflect.Method;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.ArrayList;
import Java.util.List;
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;
}
}
jRegistryKey を使う前にこれをやった。それはあなたが必要とすることをすることができるLGPL Java/JNIライブラリです。これは私がレジストリエディタを使ってレジストリ編集を有効にする方法の例です。レジストリを通してWindowsで自分自身のために "Show Folder Options"オプションも選択できます。
import Java.io.File;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RegistryValue;
import ca.beq.util.win32.registry.RootKey;
import ca.beq.util.win32.registry.ValueType;
public class FixStuff {
private static final String REGEDIT_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
private static final String REGEDIT_VALUE = "DisableRegistryTools";
private static final String REGISTRY_LIBRARY_PATH = "\\lib\\jRegistryKey.dll";
private static final String FOLDER_OPTIONS_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
private static final String FOLDER_OPTIONS_VALUE = "NoFolderOptions";
public static void main(String[] args) {
//Load JNI library
RegistryKey.initialize( new File(".").getAbsolutePath()+REGISTRY_LIBRARY_PATH );
enableRegistryEditing(true);
enableShowFolderOptions(true);
}
private static void enableShowFolderOptions(boolean enable) {
RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER,FOLDER_OPTIONS_KEY);
RegistryKey key2 = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE,FOLDER_OPTIONS_KEY);
RegistryValue value = new RegistryValue();
value.setName(FOLDER_OPTIONS_VALUE);
value.setType(ValueType.REG_DWORD_LITTLE_ENDIAN);
value.setData(enable?0:1);
if(key.hasValue(FOLDER_OPTIONS_VALUE)) {
key.setValue(value);
}
if(key2.hasValue(FOLDER_OPTIONS_VALUE)) {
key2.setValue(value);
}
}
private static void enableRegistryEditing(boolean enable) {
RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER,REGEDIT_KEY);
RegistryValue value = new RegistryValue();
value.setName(REGEDIT_VALUE);
value.setType(ValueType.REG_DWORD_LITTLE_ENDIAN);
value.setData(enable?0:1);
if(key.hasValue(REGEDIT_VALUE)) {
key.setValue(value);
}
}
}
はい。Java.util.PreferencesAPIを使用しています。Windowsの実装ではレジストリをバックエンドとして使用しているためです。
結局それはあなたが何をしたいのかに依存します:あなたのアプリのための設定を保存することは設定がまさにすばらしいことをするものです。アプリと関係のないレジストリキーを実際に変更したい場合は、Mark(ここでは恥知らずなもの)で説明されているように、いくつかのJNIアプリが必要になります。
簡単なグーグルから:JNIWrapperのためのWinPackをチェックしてください。それは読みと書きを含む完全なWindowsレジストリアクセスサポートを持っています。
WinPack Demoには、例としてRegistry Viewerが実装されています。
http://www.teamdev.com/jniwrapper/winpack/#registry_access で確認してください。
そして...
JNIRegistry @ http://www.trustice.com/Java/jnireg/ も試してみてください
レジストリの読み書きを担当する外部アプリを起動するオプションもあります。
簡単なグーグルから:
JNIWrapperのWinPackを確認してください。それは読みと書きを含む完全なWindowsレジストリアクセスサポートを持っています。
WinPack Demoには、例としてRegistry Viewerが実装されています。
http://www.teamdev.com/jniwrapper/winpack/#registry_access で確認してください。
そして...
JNIRegistry @ http://www.trustice.com/Java/jnireg/ も試してみてください
レジストリの読み書きを担当する外部アプリを起動するオプションもあります。
これがOlegのソリューションの修正版です。私のシステム(Windows Server 2003)では、 "reg query"の出力がタブ( '\ t')ではなく4つのスペースで区切られていることに気づきました。
スレッドが必要ないので、私もソリューションを単純化しました。
public static final String readRegistry(String location, String key)
{
try
{
// Run reg query, then read output with StreamReader (internal class)
Process process = Runtime.getRuntime().exec("reg query " +
'"'+ location + "\" /v " + key);
InputStream is = process.getInputStream();
StringBuilder sw = new StringBuilder();
try
{
int c;
while ((c = is.read()) != -1)
sw.append((char)c);
}
catch (IOException e)
{
}
String output = sw.toString();
// Output has the following format:
// \n<Version information>\n\n<key> <registry type> <value>\r\n\r\n
int i = output.indexOf("REG_SZ");
if (i == -1)
{
return null;
}
sw = new StringBuilder();
i += 6; // skip REG_SZ
// skip spaces or tabs
for (;;)
{
if (i > output.length())
break;
char c = output.charAt(i);
if (c != ' ' && c != '\t')
break;
++i;
}
// take everything until end of line
for (;;)
{
if (i > output.length())
break;
char c = output.charAt(i);
if (c == '\r' || c == '\n')
break;
sw.append(c);
++i;
}
return sw.toString();
}
catch (Exception e)
{
return null;
}
}
すでに述べたように、Preferences APIはレジストリを使用して設定を保存しますが、レジストリ全体にアクセスすることはできません。
しかし、David Croftという著作権侵害者は、SunのPreferences API実装でメソッドを使用することが可能であることを確認しました JNIなしでJavaからWindowsレジストリを読み取る 。いくつかの危険がありますが、それは一見の価値があります。
Windowsレジストリを扱うJNDIサービスプロバイダはほとんどありません。
http://Java.Sun.com/products/jndi/serviceproviders.html を観察することができます。
元の投稿に感謝します。私はこのユーティリティクラスを再スキンし、それが以前に持っていた欠陥を思いついた、それがここに投稿するので他の人を助けるかもしれないと思った。私はまたいくつかの追加のユーティリティメソッドを追加しました。今ではWindowsレジストリ内の任意のファイルを読み取ることができます(REG_DWORD、REG_BINARY、REG_EXPAND_SZなどを含む)。すべての方法は魅力的に働きます。コピーして貼り付けるだけでうまくいきます。これは、スキンを変更して変更したクラスです。
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.lang.reflect.InvocationTargetException;
import Java.lang.reflect.Method;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.StringTokenizer;
import Java.util.prefs.Preferences;
public class WinRegistry {
private static final int REG_SUCCESS = 0;
private static final int REG_NOTFOUND = 2;
private static final int KEY_READ = 0x20019;
private static final int REG_ACCESSDENIED = 5;
private static final int KEY_ALL_ACCESS = 0xf003f;
public static final int HKEY_CLASSES_ROOT = 0x80000000;
public static final int HKEY_CURRENT_USER = 0x80000001;
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
private static final String CLASSES_ROOT = "HKEY_CLASSES_ROOT";
private static final String CURRENT_USER = "HKEY_CURRENT_USER";
private static final String LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
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();
}
}
/**
* Reads value for the key from given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @param key
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static String valueForKey(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if (hkey == HKEY_LOCAL_MACHINE)
return valueForKey(systemRoot, hkey, path, key);
else if (hkey == HKEY_CURRENT_USER)
return valueForKey(userRoot, hkey, path, key);
else
return valueForKey(null, hkey, path, key);
}
/**
* Reads all key(s) and value(s) from given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @return the map of key(s) and corresponding value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static Map<String, String> valuesForPath(int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if (hkey == HKEY_LOCAL_MACHINE)
return valuesForPath(systemRoot, hkey, path);
else if (hkey == HKEY_CURRENT_USER)
return valuesForPath(userRoot, hkey, path);
else
return valuesForPath(null, hkey, path);
}
/**
* Read all the subkey(s) from a given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @return the subkey(s) list
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> subKeysForPath(int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE)
return subKeysForPath(systemRoot, hkey, path);
else if (hkey == HKEY_CURRENT_USER)
return subKeysForPath(userRoot, hkey, path);
else
return subKeysForPath(null, hkey, path);
}
/**
* 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
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue(int hkey, String key, String valueName, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE)
writeStringValue(systemRoot, hkey, key, valueName, value);
else if (hkey == HKEY_CURRENT_USER)
writeStringValue(userRoot, hkey, key, valueName, value);
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
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE)
rc = deleteValue(systemRoot, hkey, key, value);
else if (hkey == HKEY_CURRENT_USER)
rc = deleteValue(userRoot, hkey, key, value);
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)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS)});
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 valueForKey(Preferences root, int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {new Integer(handles[0]), toCstr(key)});
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
return (valb != null ? parseValue(valb) : queryValueForKey(hkey, path, key));
}
private static String queryValueForKey(int hkey, String path, String key) throws IOException {
return queryValuesForPath(hkey, path).get(key);
}
private static Map<String,String> valuesForPath(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
HashMap<String, String> results = new HashMap<String,String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] {new Integer(handles[0])});
int count = info[2]; // Fixed: info[0] was being used here
int maxlen = info[4]; // while info[3] was being used here, causing wrong results
for(int index=0; index<count; index++) {
byte[] valb = (byte[]) regEnumValue.invoke(root, new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
String vald = parseValue(valb);
if(valb == null || vald.isEmpty())
return queryValuesForPath(hkey, path);
results.put(vald, valueForKey(root, hkey, path, vald));
}
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
return results;
}
/**
* Searches recursively into the path to find the value for key. This method gives
* only first occurrence value of the key. If required to get all values in the path
* recursively for this key, then {@link #valuesForKeyPath(int hkey, String path, String key)}
* should be used.
* @param hkey
* @param path
* @param key
* @param list
* @return the value of given key obtained recursively
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static String valueForKeyPath(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
String val;
try {
val = valuesForKeyPath(hkey, path, key).get(0);
} catch(IndexOutOfBoundsException e) {
throw new IllegalArgumentException("The system can not find the key: '"+key+"' after "
+ "searching the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
}
return val;
}
/**
* Searches recursively into given path for particular key and stores obtained value in list
* @param hkey
* @param path
* @param key
* @param list
* @return list containing values for given key obtained recursively
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static List<String> valuesForKeyPath(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
List<String> list = new ArrayList<String>();
if (hkey == HKEY_LOCAL_MACHINE)
return valuesForKeyPath(systemRoot, hkey, path, key, list);
else if (hkey == HKEY_CURRENT_USER)
return valuesForKeyPath(userRoot, hkey, path, key, list);
else
return valuesForKeyPath(null, hkey, path, key, list);
}
private static List<String> valuesForKeyPath(Preferences root, int hkey, String path, String key, List<String> list)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if(!isDirectory(root, hkey, path)) {
takeValueInListForKey(hkey, path, key, list);
} else {
List<String> subKeys = subKeysForPath(root, hkey, path);
for(String subkey: subKeys) {
String newPath = path+"\\"+subkey;
if(isDirectory(root, hkey, newPath))
valuesForKeyPath(root, hkey, newPath, key, list);
takeValueInListForKey(hkey, newPath, key, list);
}
}
return list;
}
/**
* Takes value for key in list
* @param hkey
* @param path
* @param key
* @param list
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
private static void takeValueInListForKey(int hkey, String path, String key, List<String> list)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
String value = valueForKey(hkey, path, key);
if(value != null)
list.add(value);
}
/**
* Checks if the path has more subkeys or not
* @param root
* @param hkey
* @param path
* @return true if path has subkeys otherwise false
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static boolean isDirectory(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return !subKeysForPath(root, hkey, path).isEmpty();
}
private static List<String> subKeysForPath(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
List<String> results = new ArrayList<String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
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[] valb = (byte[]) regEnumKeyEx.invoke(root, new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
results.add(parseValue(valb));
}
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)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS)});
regSetValueEx.invoke(root, new Object[] {new Integer(handles[0]), toCstr(valueName), toCstr(value)});
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
}
/**
* Makes cmd query for the given hkey and path then executes the query
* @param hkey
* @param path
* @return the map containing all results in form of key(s) and value(s) obtained by executing query
* @throws IOException
*/
private static Map<String, String> queryValuesForPath(int hkey, String path) throws IOException {
String line;
StringBuilder builder = new StringBuilder();
Map<String, String> map = new HashMap<String, String>();
Process process = Runtime.getRuntime().exec("reg query \""+getParentKey(hkey)+"\\" + path + "\"");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = reader.readLine()) != null) {
if(!line.contains("REG_"))
continue;
StringTokenizer tokenizer = new StringTokenizer(line, " \t");
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if(token.startsWith("REG_"))
builder.append("\t ");
else
builder.append(token).append(" ");
}
String[] arr = builder.toString().split("\t");
map.put(arr[0].trim(), arr[1].trim());
builder.setLength(0);
}
return map;
}
/**
* Determines the string equivalent of hkey
* @param hkey
* @return string equivalent of hkey
*/
private static String getParentKey(int hkey) {
if(hkey == HKEY_CLASSES_ROOT)
return CLASSES_ROOT;
else if(hkey == HKEY_CURRENT_USER)
return CURRENT_USER;
else if(hkey == HKEY_LOCAL_MACHINE)
return LOCAL_MACHINE;
return null;
}
/**
*Intern method which adds the trailing \0 for the handle with Java.dll
* @param str String
* @return byte[]
*/
private static byte[] toCstr(String str) {
if(str == null)
str = "";
return (str += "\0").getBytes();
}
/**
* Method removes the trailing \0 which is returned from the Java.dll (just if the last sign is a \0)
* @param buf the byte[] buffer which every read method returns
* @return String a parsed string without the trailing \0
*/
private static String parseValue(byte buf[]) {
if(buf == null)
return null;
String ret = new String(buf);
if(ret.charAt(ret.length()-1) == '\0')
return ret.substring(0, ret.length()-1);
return ret;
}
}
メソッドの使用例は以下のとおりです。
以下のメソッドは与えられたパスからキーの値を取得します。
String hex = WinRegistry.valueForKey(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update", "AUOptions");
このメソッドは、指定されたパスのすべてのデータを(キーと値の形式で)取得します。
Map<String, String> map = WinRegistry.valuesForPath(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WSMAN");
このメソッドは、指定されたパスからキーの値を再帰的に取得します。
String val = WinRegistry.valueForKeyPath(WinRegistry.HKEY_LOCAL_MACHINE, "System", "TypeID");
そしてこれは与えられたパスからキーのすべての値を再帰的に取得します。
List<String> list = WinRegistry.valuesForKeyPath(
WinRegistry.HKEY_LOCAL_MACHINE, //HKEY "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", //path "DisplayName" //Key
);
ここで上記のコードで私はwindowsシステムにインストールされているすべてのソフトウェア名を検索しました。
注:これらのメソッドのドキュメントを参照してください
そしてこれは与えられたパスのすべてのサブキーを取得します。
List<String> list3 = WinRegistry.subKeysForPath(WinRegistry.HKEY_CURRENT_USER, "Software");
重要な注意:このプロセスでは読み取り専用のメソッドだけを変更しました。createKey、deleteKeyなどの書き込み専用のメソッドは変更していません。これらはまだ受け取ったものと同じです。
レジスタに書き込むための最善の方法は、おそらくreg import
ネイティブWindowsコマンドを使用し、それにレジストリから何かをエクスポートすることによって生成された.reg
ファイルへのファイルパスを与えることです。
読み取りはreg query
コマンドで行われます。ドキュメントも参照してください。 https://technet.Microsoft.com/ja-jp/library/cc742028.aspx
したがって、次のコードは一目瞭然です。
import Java.io.BufferedReader;
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.IOException;
import Java.io.InputStreamReader;
public class WindowsRegistry
{
public static void importSilently(String regFilePath) throws IOException,
InterruptedException
{
if (!new File(regFilePath).exists())
{
throw new FileNotFoundException();
}
Process importer = Runtime.getRuntime().exec("reg import " + regFilePath);
importer.waitFor();
}
public static void overwriteValue(String keyPath, String keyName,
String keyValue) throws IOException, InterruptedException
{
Process overwriter = Runtime.getRuntime().exec(
"reg add " + keyPath + " /t REG_SZ /v \"" + keyName + "\" /d "
+ keyValue + " /f");
overwriter.waitFor();
}
public static String getValue(String keyPath, String keyName)
throws IOException, InterruptedException
{
Process keyReader = Runtime.getRuntime().exec(
"reg query \"" + keyPath + "\" /v \"" + keyName + "\"");
BufferedReader outputReader;
String readLine;
StringBuffer outputBuffer = new StringBuffer();
outputReader = new BufferedReader(new InputStreamReader(
keyReader.getInputStream()));
while ((readLine = outputReader.readLine()) != null)
{
outputBuffer.append(readLine);
}
String[] outputComponents = outputBuffer.toString().split(" ");
keyReader.waitFor();
return outputComponents[outputComponents.length - 1];
}
}
Preferences APIアプローチでは、レジストリのすべてのブランチにアクセスすることはできません。実際、Preferences APIがその設定を保存している場所へのアクセスのみを提供します。 .NETのような一般的なレジストリ処理APIではありません。
Markが示しているように、すべてのキーを読み書きするには、JNIまたは外部ツールを使用することをお勧めします。
WinRun4J を試すことができます。これは、WindowsのJavaランチャーおよびサービスホストですが、レジストリにアクセスするためのライブラリも提供します。
(ところで私はこのプロジェクトに取り組んでいるので、質問があれば教えてください)
Java.util.prefs
パッケージは、アプリケーションがユーザーおよびシステムの設定とデータ設定を格納および取得する方法を提供します。これらの嗜好データは、格納されている実装依存のバッキングに永続的に格納されます。たとえば、Windowsオペレーティングシステムでは、Windowsレジストリに格納されます。
これらのデータを読み書きするにはJava.util.prefs.Preferences
クラスを使います。以下のコードは、レジストリ内のHKCU
およびHKLM
を読み書きする方法を示しています。
import Java.util.prefs.Preferences;
public class RegistryDemo {
public static final String PREF_KEY = "org.username";
public static void main(String[] args) {
//
// Write Preferences information to HKCU (HKEY_CURRENT_USER),
// HKCU\Software\JavaSoft\Prefs\org.username
//
Preferences userPref = Preferences.userRoot();
userPref.put(PREF_KEY, "xyz");
//
// Below we read back the value we've written in the code above.
//
System.out.println("Preferences = "
+ userPref.get(PREF_KEY, PREF_KEY + " was not found."));
//
// Write Preferences information to HKLM (HKEY_LOCAL_MACHINE),
// HKLM\Software\JavaSoft\Prefs\org.username
//
Preferences systemPref = Preferences.systemRoot();
systemPref.put(PREF_KEY, "xyz");
//
// Read back the value we've written in the code above.
//
System.out.println("Preferences = "
+ systemPref.get(PREF_KEY, PREF_KEY + " was not found."));
}
}
@ Davidの答えに対する私の前回の編集は拒否されました。これに関するいくつかの役に立つ情報があります。
SunはJDKの一部としてWindows用のPreferences
クラスを実装しているため、この「魔法」は機能しますが、 package private です。実装の一部はJNIを使用します。
Java.util.prefs.WindowsPreferences
からのプライベートクラスをパッケージ化する: http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/7-b147/Java/util/prefs/WindowsPreferences.Java =実装は実行時にここでファクトリメソッドを使用して選択されます。 http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/7-b147/Java/util/prefs/ Preferences.Java#Preferences.0factory
本当の質問:なぜOpenJDKはこのAPIを一般に公開しないのですか?
さらに別の図書館...
https://code.google.com/p/Java-registry/
これは、一時ファイルへの読み書きを行う、カバーの下にあるreg.exeを起動します。私はそれを使い終わったわけではありませんが、かなり包括的な実装のように見えます。私がそれを使用したならば、私は飛び込んで、子プロセスのより良い管理を追加するかもしれません。
WinPack Demoには、例としてRegistry Viewerが実装されています。
http://www.jniwrapper.com/winpack_features.jsp#registry で確認してください。
ところで、WinPackは次のアドレスに移動されました。
これはかなり古いですが、私はWindowsプラットフォームで使用するためのより良いユーティリティはregini
であろうと思います:
Processへの単一の呼び出し
Runtime.getRuntime().exec("regini <your script file abs path here>");
すべての魔法をやります。 javaw.exe引数を追加するためにレジストリの変更を必要とするservany.exeを使用してWindowsサービスとしてjarを作成しながら、私はそれを試してみました、そしてそれは完全に動作します。これを読むことをお勧めします。 http://support.Microsoft.com/kb/264584
これはクレイジーでした...私はここの投稿の1つからコードを取りました、それがDWORD値を読んでいないことを述べているもののうちの18のより多くのコメントがあるのを見逃していました...
いずれにせよ、私はそのコードの地獄をifやメソッドの少ないものにリファクタリングしました...
Enumは少し洗練されているかもしれませんが、私が数値やバイト配列を読む方法に失敗して失敗するとすぐに、私はあきらめました...
だからここにあります:
package com.nu.art.software.utils;
import Java.lang.reflect.Method;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.prefs.Preferences;
/**
*
* @author TacB0sS
*/
public class WinRegistry_TacB0sS {
public static final class RegistryException
extends Exception {
private static final long serialVersionUID = -8799947496460994651L;
public RegistryException(String message, Throwable e) {
super(message, e);
}
public RegistryException(String message) {
super(message);
}
}
public static final int KEY_WOW64_32KEY = 0x0200;
public static final int KEY_WOW64_64KEY = 0x0100;
public static final int REG_SUCCESS = 0;
public static final int REG_NOTFOUND = 2;
public static final int REG_ACCESSDENIED = 5;
private static final int KEY_ALL_ACCESS = 0xf003f;
private static final int KEY_READ = 0x20019;
public enum WinRegistryKey {
User(Preferences.userRoot(), 0x80000001), ;
// System(Preferences.systemRoot(), 0x80000002);
private final Preferences preferencesRoot;
private final Integer key;
private WinRegistryKey(Preferences preferencesRoot, int key) {
this.preferencesRoot = preferencesRoot;
this.key = key;
}
}
private enum WinRegistryMethod {
OpenKey("WindowsRegOpenKey", int.class, byte[].class, int.class) {
@Override
protected void verifyReturnValue(Object retValue)
throws RegistryException {
int[] retVal = (int[]) retValue;
if (retVal[1] != REG_SUCCESS)
throw new RegistryException("Action Failed, Return Code: " + retVal[1]);
}
},
CreateKeyEx("WindowsRegCreateKeyEx", int.class, byte[].class) {
@Override
protected void verifyReturnValue(Object retValue)
throws RegistryException {
int[] retVal = (int[]) retValue;
if (retVal[1] != REG_SUCCESS)
throw new RegistryException("Action Failed, Return Code: " + retVal[1]);
}
},
DeleteKey("WindowsRegDeleteKey", int.class, byte[].class) {
@Override
protected void verifyReturnValue(Object retValue)
throws RegistryException {
int retVal = ((Integer) retValue).intValue();
if (retVal != REG_SUCCESS)
throw new RegistryException("Action Failed, Return Code: " + retVal);
}
},
DeleteValue("WindowsRegDeleteValue", int.class, byte[].class) {
@Override
protected void verifyReturnValue(Object retValue)
throws RegistryException {
int retVal = ((Integer) retValue).intValue();
if (retVal != REG_SUCCESS)
throw new RegistryException("Action Failed, Return Code: " + retVal);
}
},
CloseKey("WindowsRegCloseKey", int.class),
QueryValueEx("WindowsRegQueryValueEx", int.class, byte[].class),
EnumKeyEx("WindowsRegEnumKeyEx", int.class, int.class, int.class),
EnumValue("WindowsRegEnumValue", int.class, int.class, int.class),
QueryInfoKey("WindowsRegQueryInfoKey", int.class),
SetValueEx("WindowsRegSetValueEx", int.class, byte[].class, byte[].class);
private Method method;
private WinRegistryMethod(String methodName, Class<?>... classes) {
// WinRegistryKey.User.preferencesRoot.getClass().getMDeclaredMethods()
try {
method = WinRegistryKey.User.preferencesRoot.getClass().getDeclaredMethod(methodName, classes);
} catch (Exception e) {
System.err.println("Error");
System.err.println(e);
}
method.setAccessible(true);
}
public Object invoke(Preferences root, Object... objects)
throws RegistryException {
Object retValue;
try {
retValue = method.invoke(root, objects);
verifyReturnValue(retValue);
} catch (Throwable e) {
String params = "";
if (objects.length > 0) {
params = objects[0].toString();
for (int i = 1; i < objects.length; i++) {
params += ", " + objects[i];
}
}
throw new RegistryException("Error invoking method: " + method + ", with params: (" + params + ")", e);
}
return retValue;
}
protected void verifyReturnValue(Object retValue)
throws RegistryException {}
}
private WinRegistry_TacB0sS() {}
public static String readString(WinRegistryKey regKey, String key, String valueName)
throws RegistryException {
int retVal = ((int[]) WinRegistryMethod.OpenKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key),
new Integer(KEY_READ)))[0];
byte[] retValue = (byte[]) WinRegistryMethod.QueryValueEx.invoke(regKey.preferencesRoot, retVal,
toCstr(valueName));
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal);
/*
* Should this return an Empty String.
*/
return (retValue != null ? new String(retValue).trim() : null);
}
public static Map<String, String> readStringValues(WinRegistryKey regKey, String key)
throws RegistryException {
HashMap<String, String> results = new HashMap<String, String>();
int retVal = ((int[]) WinRegistryMethod.OpenKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key),
new Integer(KEY_READ)))[0];
int[] info = (int[]) WinRegistryMethod.QueryInfoKey.invoke(regKey.preferencesRoot, retVal);
int count = info[2]; // count
int maxlen = info[3]; // value length max
for (int index = 0; index < count; index++) {
byte[] name = (byte[]) WinRegistryMethod.EnumValue.invoke(regKey.preferencesRoot, retVal,
new Integer(index), new Integer(maxlen + 1));
String value = readString(regKey, key, new String(name));
results.put(new String(name).trim(), value);
}
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal);
return results;
}
public static List<String> readStringSubKeys(WinRegistryKey regKey, String key)
throws RegistryException {
List<String> results = new ArrayList<String>();
int retVal = ((int[]) WinRegistryMethod.OpenKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key),
new Integer(KEY_READ)))[0];
int[] info = (int[]) WinRegistryMethod.QueryInfoKey.invoke(regKey.preferencesRoot, retVal);
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[]) WinRegistryMethod.EnumValue.invoke(regKey.preferencesRoot, retVal,
new Integer(index), new Integer(maxlen + 1));
results.add(new String(name).trim());
}
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal);
return results;
}
public static void createKey(WinRegistryKey regKey, String key)
throws RegistryException {
int[] retVal = (int[]) WinRegistryMethod.CreateKeyEx.invoke(regKey.preferencesRoot, regKey.key, toCstr(key));
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal[0]);
}
public static void writeStringValue(WinRegistryKey regKey, String key, String valueName, String value)
throws RegistryException {
int retVal = ((int[]) WinRegistryMethod.OpenKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key),
new Integer(KEY_ALL_ACCESS)))[0];
WinRegistryMethod.SetValueEx.invoke(regKey.preferencesRoot, retVal, toCstr(valueName), toCstr(value));
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal);
}
public static void deleteKey(WinRegistryKey regKey, String key)
throws RegistryException {
WinRegistryMethod.DeleteKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key));
}
public static void deleteValue(WinRegistryKey regKey, String key, String value)
throws RegistryException {
int retVal = ((int[]) WinRegistryMethod.OpenKey.invoke(regKey.preferencesRoot, regKey.key, toCstr(key),
new Integer(KEY_ALL_ACCESS)))[0];
WinRegistryMethod.DeleteValue.invoke(regKey.preferencesRoot, retVal, toCstr(value));
WinRegistryMethod.CloseKey.invoke(regKey.preferencesRoot, retVal);
}
// 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;
}
}
注:これは、他にはありませんが、他の文字列は読みません!!!!!