it-swarm.cn

使用Java读/写Windows注册表

如何使用Java读/写Windows注册表?

307
Dichkaun

我知道这个问题已经过时了,但这是google上第一个“Java读/写注册表”的搜索结果。最近我发现了这段令人惊奇的代码:

  • 可以读/写注册表的任何部分。
  • 不使用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 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;
  }
}

我无法找到并赞扬此代码的原作者。如果您发现任何详细信息,请添加评论,我将在此处添加。

316
David

您实际上并不需要第三方包。 Windows为所有注册表操作都有一个reg实用程序。要获取命令格式,请转到DOS propmt并键入:

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);
    }
}

122
Oleg Ryaboy

Java Native Access(JNA) 是一个很好的项目,用于处理本机库,并通过 Advapi32UtilAdvapi32 支持平台库(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");
    }
}
63
John McCarthy

我增加了David最初发布的Pure Java代码,允许从64位JVM访问注册表的32位部分,反之亦然。我认为其他任何答案都没有解决这个问题。

这里是:

/**
 * Pure Java Windows Registry access.
 * Modified by [email protected](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;
  }
}
26
Petrucio

我在使用 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);
    }
}

}
23
Alex Argo

是的,使用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/

还可以选择调用外部应用程序,该应用程序负责读/写注册表。

20
Epaga

从快速谷歌:

检查WinPack for JNIWrapper。它具有完整的Windows注册表访问支持,包括阅读和写作。

WinPack演示以Registry Viewer实现为例。

检查 http://www.teamdev.com/jniwrapper/winpack/#registry_access

和...

还有尝试JNIRegistry @ http://www.trustice.com/Java/jnireg/

还可以选择调用外部应用程序,该应用程序负责读/写注册表。

11
Mark Ingram

这是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;
  }

}

8
gousli

如前所述,Preferences API使用注册表来存储首选项,但不能用于访问整个注册表。

然而,一个名叫David Croft的盗版者已经知道,可以使用Sun的Preferences API实现中的方法 从没有JNI的Java读取Windows注册表 。这有一些危险,但值得一看。

5
Tom Anderson

很少有JNDI服务提供商可以使用Windows注册表。

人们可以观察 http://Java.Sun.com/products/jndi/serviceproviders.html

5
Ignat

感谢原帖。我已经重新设计了这个实用程序类,并提出了它之前的缺陷,认为它可能会帮助其他人如此发布。我还添加了一些额外的实用方法。现在它能够读取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等编写目的方法。它们仍然与我收到的相同。

5
pratapvaibhav19

写入寄存器的最佳方法可能是使用reg import本机Windows命令,并为其提供.reg文件的文件路径,该文件是通过从注册表导出内容生成的。

使用reg query命令完成读取。另请参阅文档: https://technet.Microsoft.com/en-us/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];
    }
}
4
BullyWiiPlaza

Preferences API方法不允许您访问注册表的所有分支。实际上,它只允许您访问Preferences API存储的位置,以及首选项。它不是像.NET那样的通用注册表处理API

如Mark所示,为了读取/写入每个键,我猜JNI或外部工具将是采用的方法。

4
Vinko Vrsalovic

你可以试试 WinRun4J 。这是一个Windows Java启动程序和服务主机,但它还提供了一个用于访问注册表的库。

(顺便说一下我在这个项目上工作,如果你有任何问题,请告诉我)

3
Peter Smith

Java.util.prefs包为应用程序提供了一种存储和检索用户和系统首选项以及数据配置的方法。这些首选项数据将持久存储在存储的依赖于实现的后备中。例如在Windows操作系统中将存储在Windows注册表中。

要编写和读取这些数据,我们使用Java.util.prefs.Preferences类。下面的代码显示了如何读取和写入注册表中的HKCUHKLM

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."));
    }
}
2
Vipul Paralikar

我以前对@ David的答案的编辑被拒绝了。以下是一些有用的信息。

这种“神奇”的作用是因为Sun为Windows实现了Preferences类作为JDK的一部分,但它是 package private 。部分实现使用JNI。

在运行时使用工厂方法选择实现: http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/7-b147/Java/util/prefs/Preferences。 Java#Preferences.0factory

真正的问题:为什么OpenJDK不公开这个API?

2
kevinarpe

又一个图书馆......

https://code.google.com/p/Java-registry/

这个启动reg.exe,读取/写入临时文件。我最终没有使用它,但它看起来像一个非常全面的实现。如果我确实使用它,我可能会潜入并添加一些更好的子进程管理。

1
Ryan

WinPack演示以Registry Viewer实现为例。

检查 http://www.jniwrapper.com/winpack_features.jsp#registry

BTW,WinPack已移至以下地址:

http://www.teamdev.com/jniwrapper/winpack/

0
Roman

虽然这是相当古老的,但我想在Windows平台上使用的更好的实用程序将是regini

单次调用流程:

Runtime.getRuntime().exec("regini <your script file abs path here>");

会做所有的魔术。我试过它,同时使用servany.exe将jar作为windows服务,这需要在注册表中进行更改以添加javaw.exe参数,并且它完美地工作。你可能想读这个: http://support.Microsoft.com/kb/264584

0
Johnydep

这很疯狂......我从这里的一个帖子中取了代码,没看到还有18条评论,其中一条表明它没有读取dword值...

无论如何,我已经将那些代码的地狱重构为更少的ifs和方法......

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;
    }
}

注意:这不会读任何字符串但是!

0
TacB0sS