如何使用Java读/写Windows注册表?
我知道这个问题已经过时了,但这是google上第一个"java read/write to registry"的搜索结果.最近我发现了这段令人惊奇的代码:
可以读/写注册表的任何部分.
不使用JNI.
不使用任何第三方/外部应用程序.
不使用WINDOWS API(直接)
这是纯Java代码.
它通过实际访问类中的私有方法来使用反射来工作java.util.prefs.Preferences
.这个类的内部很复杂,但类本身很容易使用.
例如,以下代码从注册表获取确切的Windows分发:
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 MapreadStringValues(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 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 readStringValues (Preferences root, int hkey, String key) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { HashMap results = new HashMap (); 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 readStringSubKeys (Preferences root, int hkey, String key) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { List results = new ArrayList (); 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 我无法找到并赞扬此代码的原作者.如果您发现任何详细信息,请添加评论,我将在此处添加.
**这是根据Apache许可**进行许可**给了一些[谷歌搜索](http://svn.apache.org/repos/asf/incubator/npanday/trunk/components/dotnet-registry/src/main/java/ npanday /注册表/ IMPL/WinRegistry.java).
这非常讨厌 - 它涉及通过反射调用非公共方法.换句话说,如Javadocs中所述,您将超出首选项合同,并且此代码可能会在Oracle推出新更新时中断.
这段代码有一个小错误; readStringSubKeys枚举注册表项的子键不起作用.将私有readStringSubKeys函数中的"int count = info [2]; // count"替换为"int count = info [0]; // count",这将解决它.可以在反映的WindowsPreferences.SUBKEYS_NUMBER字段中看到正确的值.
我怎么能读这个dword?他的样本对于一个字符串来说效果很好,但我现在需要获得一个实际值来阅读.刚出来就是null.
@Qix您确定作者没有从这里获得该课程吗?据我所知,提交日期是*发布后*.我很久以前就在论坛上找到了这个.
此代码可能不再适用于`Java 9`,因为它会生成以下警告:"发生了非法反射访问操作"
可以在RéalGagnon的网站www.rgagnon.com/javadetails/java-0630.html找到带有"灵感来源"链接的代码?
*JAW DROP*,哇!希望我能不止一次地投票.我使用此代码,因此成功查询存储在Win7虚拟化注册表中的密钥,Regedit和Reg CLI工具都无法提供.
哇......两个问题,什么样的疯狂的大脑催生了这个大师的作品,以及Java工程师在阅读这篇文章时,他们在墙上砸了多少头?
@nbarraille*任何具有足够访问权限的java程序.此外,这似乎在某些计算机上不起作用.我不确定它是否适用于1.7.这个hack很旧,2008年,你可以用JNA实现同样的目标.您运行的每个程序都可以读取/写入注册表,这是否可怕?
任何人都知道如何使用这些方法将dword写入注册表?
写字符串值时似乎没有用?非常混乱的API
2> Oleg Ryaboy..:您实际上并不需要第三方包.Windows为所有注册表操作都有一个reg实用程序.要获取命令格式,请转到DOS propmt并键入:
reg /?您可以通过Runtime类调用reg:
Runtime.getRuntime().exec("reg"); 使用上面的命令编辑密钥并添加新密钥很简单.要阅读注册表,你需要获得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\n\n \t \t 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); } }
这段代码很棒!但是,您的解析存在问题.在我的Windows 7安装程序中没有制表符.解析代码应该更加健壮.我已经在我的实现中更改它以查找确保它具有输出的密钥.然后我使用正则表达式在空白上拆分并获取最后一个字符串.这应该始终是密钥的值.
任何人都可以解释为什么阅读已在这里多线程?
在回答我自己的评论时,问题与此有关(/sf/ask/17360801/).基本上,reg.exe是64位,而JVM可能是32位,所以他们可以在不同的地方寻找密钥.解决方法是使用两个路径调用两次
奥列格,这真的很有用,谢谢!请注意,如果要读取process.getErrorStream()的输出,readRegistry方法可以添加第二个StreamReader.PS在"new StringWriter();;"中有一个额外的分号.
3> John McCarth..:Java Native Access(JNA)是一个用于处理本机库的优秀项目,并通过Advapi32Util和Advapi32支持平台库(platform.jar)中的Windows注册表.
更新:这里有一些代码片段,其中包含使用JNA 3.4.1使用JNA处理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"); } }
JNA 4.0+现在已获得Apache 2许可([见这里](https://github.com/twall/jna#license)).非hacky解决方案的大+1.
它是LGPL可能是一个问题,包括它在商业软件中.
根据我的经验,LGPL许可软件可以使用商业软件进行重新分配(GPL限制性更强).当然,您应该始终咨询您的法律部门(可能已经有).看起来JNA将获得双重许可,允许在发布JNA 4.0时在Apache 2.0下进行重新分发(请参阅https://github.com/twall/jna/blob/master/LICENSE).
4> Petrucio..:我增加了最初由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 MapreadStringValues(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 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 readStringValues(Preferences root, int hkey, String key, int wow64) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { HashMap results = new HashMap (); 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 readStringSubKeys(Preferences root, int hkey, String key, int wow64) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { List results = new ArrayList (); 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
5> Alex Argo..:我在使用jRegistryKey之前已经完成了这个.它是一个LGPL Java/JNI库,可以满足您的需求.以下是我如何使用它通过regedit启用注册表编辑以及通过注册表在Windows中为自己启用"显示文件夹选项"选项的示例.
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); } } }
这不支持64位!编写它的人需要你的帮助才能添加64位JVM支持.http://sourceforge.net/tracker/index.php?func=detail&aid=2966672&group_id=104321&atid=641035
6> Epaga..:是的,使用java.util.Preferences API,因为它的Windows实现使用Registry作为后端.
最后,它取决于您想要做什么:为您的应用程序存储首选项是首选项的功能.如果您想要实际更改与您的应用程序无关的注册表项,您将需要一些JNI应用程序,如Mark所述(此处无耻窃取):
从快速谷歌:检查WinPack for JNIWrapper.它具有完整的Windows注册表访问支持,包括阅读和写作.
WinPack演示以Registry Viewer实现为例.
请访问http://www.teamdev.com/jniwrapper/winpack/#registry_access
和...
还有JNIRegistry @ http://www.trustice.com/java/jnireg/
还可以选择调用外部应用程序,该应用程序负责读/写注册表.
那么,如何使用Preferences API编辑HKEY_CLASSES_ROOT?
要做到这一点,你需要一个JNI应用程序
7> Mark Ingram..:从快速谷歌:
检查WinPack for JNIWrapper.它具有完整的Windows注册表访问支持,包括阅读和写作.
WinPack演示以Registry Viewer实现为例.
请访问 http://www.teamdev.com/jniwrapper/winpack/#registry_access
和...
还有JNIRegistry @ http://www.trustice.com/java/jnireg/
还可以选择调用外部应用程序,该应用程序负责读/写注册表.
8> 小智..:这是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\n\n \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; } }
9> BullyWiiPlaz..:写入寄存器的最佳方法可能是使用本
reg import
机Windows命令,并为其提供文件的路径,该路径.reg
是通过从注册表中导出内容生成的。使用
reg query
命令完成读取。另请参阅文档:https : //technet.microsoft.com/zh-cn/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]; } }
10> pratapvaibha..:感谢原帖.我已经重新设计了这个实用程序类,并提出了它之前的缺陷,认为它可能会帮助其他人如此发布.我还添加了一些额外的实用方法.现在它能够读取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 MapvaluesForPath(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 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 valuesForPath(Preferences root, int hkey, String path) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException { HashMap results = new HashMap (); 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 valuesForKeyPath(int hkey, String path, String key) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException { List list = new ArrayList (); 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 valuesForKeyPath(Preferences root, int hkey, String path, String key, List list) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException { if(!isDirectory(root, hkey, path)) { takeValueInListForKey(hkey, path, key, list); } else { List 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 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 subKeysForPath(Preferences root, int hkey, String path) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { List results = new ArrayList (); 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 queryValuesForPath(int hkey, String path) throws IOException { String line; StringBuilder builder = new StringBuilder(); Map map = new HashMap (); 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");此方法检索指定路径的所有数据(以键和值的形式):
Mapmap = WinRegistry.valuesForPath(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WSMAN"); 此方法从给定路径以递归方式检索值:
String val = WinRegistry.valueForKeyPath(WinRegistry.HKEY_LOCAL_MACHINE, "System", "TypeID");并且这个从给定路径以递归方式检索所有值:
Listlist = WinRegistry.valuesForKeyPath( WinRegistry.HKEY_LOCAL_MACHINE, //HKEY "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", //path "DisplayName" //Key ); Here in above code I retrieved all installed software names in windows system.
Note: See the documentation of these methodsAnd this one retrieves all subkeys of the given path:
Listlist3 = WinRegistry.subKeysForPath(WinRegistry.HKEY_CURRENT_USER, "Software"); Important Note: I have modified only reading purpose methods in this process, not the writing purpose methods like createKey, deleteKey etc. They still are same as I recieved them.
这个解决方案要非常小心,它与接受的答案不一样.在最底层,它取代了对Preference类的调用,并将shell命令转换为"reg query"命令,但它看起来就像你接受的答案一样,你可能不会马上意识到这一点.
11> 小智..:很少有JNDI服务提供商可以使用Windows注册表.
人们可以观察http://java.sun.com/products/jndi/serviceproviders.html.
12> Tom Anderson..:如前所述,Preferences API使用注册表来存储首选项,但不能用于访问整个注册表.
然而,一个名叫David Croft的盗版者已经知道,可以使用Sun的Preferences API实现方法,从Java中读取Windows注册表而不使用JNI.这有一些危险,但值得一看.