Чтение / запись в реестр Windows с использованием Java


323

Как можно читать / записывать в реестр Windows, используя Java?


Я бы сказал , что самый простой способ используетcom.sun.deploy.association.utility.WinRegistryWrapper
Jire

@Jire Это лучше, чем принятое решение во всех отношениях, за исключением того, что вам нужно включить в проект «deploy.jar» из вашей установки Java - он не включается автоматически. Он также страдает от той же большой проблемы - он не может обрабатывать ничего, кроме строк (даже не многострочных). Вы можете добавить его в качестве нового ответа с некоторыми примерами использования. Если у вас недостаточно высокого представителя, чтобы отвечать на этот вопрос, дайте мне знать, и я сделаю это за вас.
Билл К

Ответы:


328

Я знаю, что этот вопрос старый, но это первый результат поиска в Google "java для чтения / записи в реестр". Недавно я нашел этот удивительный кусок кода, который:

  • Может читать / писать в любой части реестра.
  • НЕ ИСПОЛЬЗУЕТ JNI.
  • НЕ ИСПОЛЬЗУЕТ ЛЮБУЮ 3-Й СТОРОНУ / ВНЕШНИЕ ПРИЛОЖЕНИЯ ДЛЯ РАБОТЫ.
  • НЕ ИСПОЛЬЗУЕТ 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;
  }
}

Оригинальный Автор: Apache.

Источник библиотеки: https://github.com/apache/npanday/tree/trunk/components/dotnet-registry/src/main/java/npanday/registry


11
В этом коде есть небольшая ошибка; readStringSubKeys для перечисления подразделов раздела реестра не работает. Замените "int count = info [2]; // count" в закрытой функции readStringSubKeys на "int count = info [0]; // count", и это исправит это. Правильное значение можно увидеть в отраженном поле WindowsPreferences.SUBKEYS_NUMBER.
davenpcj

11
Как мне заставить это читать меч? Его пример отлично работает для строки, но мне нужно вывести фактическое значение, чтобы прочитать его сейчас. Просто выходит как ноль.
Jerhynsoen

27
Это лицензировано под лицензией Apache, учитывая некоторые поиски Google .
Qix - МОНИКА БЫЛА ПОВРЕЖДЕНА

25
Это очень неприятно - это подразумевает использование закрытых методов через рефлексию. Другими словами, вы выходите за рамки контракта Preferences, как описано в Javadocs, и этот код может прерваться каждый раз, когда Oracle выпускает новое обновление.
Торбьерн Равн Андерсен

11
Этот код может больше не работать, Java 9потому что он генерирует следующее предупреждение:An illegal reflective access operation has occurred
BullyWiiPlaza

132

Вам на самом деле не нужен сторонний пакет. В Windows есть утилита reg для всех операций реестра. Чтобы получить формат команды, перейдите в DOS propmt и введите:

reg /?

Вы можете вызвать reg через класс Runtime:

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


2
Олег, это было действительно полезно, спасибо! Обратите внимание, что метод readRegistry может добавить второй StreamReader, если вы хотите прочитать выходные данные process.getErrorStream (). PS есть дополнительная точка с запятой в "new StringWriter () ;;".
Эндрю Свон

5
Этот код прекрасно работает! Тем не менее, есть проблема с вашим анализом. На моей установке Windows 7 нет символов табуляции. Код синтаксического анализа должен быть немного более надежным. Я изменил его в своей реализации, чтобы найти ключ, чтобы убедиться, что он имеет выход. Затем я использую регулярное выражение, чтобы разбить пробел и получить последнюю строку. Это всегда должно быть значение для ключа.
Майк Дж

4
Может кто-нибудь объяснить, почему чтение было сделано многопоточным здесь?
Чани

Это работает хорошо, за исключением случаев, когда в ключе есть пробелы. Для предотвращения этого следует использовать Process process = Runtime.getRuntime (). Exec ("reg query" + '"' + location +" \ "/ v \" "+ key +" \ "");
Стив Коэн

4
В ответ на мой собственный комментарий проблема связана с этим ( stackoverflow.com/questions/252297/… ). В основном reg.exe является 64-битным, тогда как JVM может быть 32-битным, поэтому они могут искать ключ в разных местах. Обходной путь состоит в том, чтобы вызвать два раза с обоими путями
Лока

72

Java Native Access (JNA) является отличным проектом для работы с нативными библиотеками и поддерживает реестр Windows в библиотеке платформы (platform.jar) через Advapi32Util и Advapi32 .

Обновление: вот фрагмент с некоторыми примерами того, как легко использовать JNA для работы с реестром Windows, используя JNA 3.4.1,

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

6
Это LGPL, которая может быть проблемой, включая его в коммерческое программное обеспечение.
likejudo

1
@likejiujitsu: Автор готов продавать коммерческие лицензии в соответствии со страницей GitHub.
Кевинарпе

1
@kevinarpe "Коммерческие лицензионные соглашения являются предметом переговоров". Отсутствие установленной цены для меня - красный флаг.
likejudo

3
По моему опыту, лицензионное программное обеспечение LGPL можно распространять вместе с коммерческим программным обеспечением (GPL гораздо более строгий). Конечно, вы всегда должны проконсультироваться с вашим юридическим отделом (и, вероятно, уже есть). Кроме того, похоже, что JNA будет иметь двойную лицензию, чтобы разрешить перераспределение в Apache 2.0 после выпуска JNA 4.0 (см. Github.com/twall/jna/blob/master/LICENSE ).
Джон Маккарти

8
JNA 4.0+ теперь имеет лицензию Apache 2 ( см. Здесь ). Большой +1 для нехакерского решения.
Дункан Джонс

26

Я увеличил Java-код Pure, изначально опубликованный Дэвидом, чтобы разрешить доступ к 32-битному разделу реестра из 64-битной JVM, и наоборот. Я не думаю, что какие-либо другие ответы касаются этого.

Вот:

/**
 * Pure Java Windows Registry access.
 * Modified by petrucio@stackoverflow(828681) to add support for
 * reading (and writing but not creating/deleting keys) the 32-bits
 * registry view from a 64-bits JVM (KEY_WOW64_32KEY)
 * and 64-bits view from a 32-bits JVM (KEY_WOW64_64KEY).
 *****************************************************************************/

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;

public class WinRegistry {
  public static final int HKEY_CURRENT_USER = 0x80000001;
  public static final int HKEY_LOCAL_MACHINE = 0x80000002;
  public static final int REG_SUCCESS = 0;
  public static final int REG_NOTFOUND = 2;
  public static final int REG_ACCESSDENIED = 5;

  public static final int KEY_WOW64_32KEY = 0x0200;
  public static final int KEY_WOW64_64KEY = 0x0100;

  private static final int KEY_ALL_ACCESS = 0xf003f;
  private static final int KEY_READ = 0x20019;
  private static Preferences userRoot = Preferences.userRoot();
  private static Preferences systemRoot = Preferences.systemRoot();
  private static Class<? extends Preferences> userClass = userRoot.getClass();
  private static Method regOpenKey = null;
  private static Method regCloseKey = null;
  private static Method regQueryValueEx = null;
  private static Method regEnumValue = null;
  private static Method regQueryInfoKey = null;
  private static Method regEnumKeyEx = null;
  private static Method regCreateKeyEx = null;
  private static Method regSetValueEx = null;
  private static Method regDeleteKey = null;
  private static Method regDeleteValue = null;

  static {
    try {
      regOpenKey     = userClass.getDeclaredMethod("WindowsRegOpenKey",     new Class[] { int.class, byte[].class, int.class });
      regOpenKey.setAccessible(true);
      regCloseKey    = userClass.getDeclaredMethod("WindowsRegCloseKey",    new Class[] { int.class });
      regCloseKey.setAccessible(true);
      regQueryValueEx= userClass.getDeclaredMethod("WindowsRegQueryValueEx",new Class[] { int.class, byte[].class });
      regQueryValueEx.setAccessible(true);
      regEnumValue   = userClass.getDeclaredMethod("WindowsRegEnumValue",   new Class[] { int.class, int.class, int.class });
      regEnumValue.setAccessible(true);
      regQueryInfoKey=userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",new Class[] { int.class });
      regQueryInfoKey.setAccessible(true);
      regEnumKeyEx   = userClass.getDeclaredMethod("WindowsRegEnumKeyEx",   new Class[] { int.class, int.class, int.class });  
      regEnumKeyEx.setAccessible(true);
      regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[] { int.class, byte[].class });
      regCreateKeyEx.setAccessible(true);  
      regSetValueEx  = userClass.getDeclaredMethod("WindowsRegSetValueEx",  new Class[] { int.class, byte[].class, byte[].class });  
      regSetValueEx.setAccessible(true); 
      regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[] { int.class, byte[].class });  
      regDeleteValue.setAccessible(true); 
      regDeleteKey   = userClass.getDeclaredMethod("WindowsRegDeleteKey",   new Class[] { int.class, byte[].class });  
      regDeleteKey.setAccessible(true); 
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  private WinRegistry() {  }

  /**
   * Read a value from key and value name
   * @param hkey   HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @param valueName
   * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
   *               or KEY_WOW64_32KEY to force access to 32-bit registry view,
   *               or KEY_WOW64_64KEY to force access to 64-bit registry view
   * @return the value
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static String readString(int hkey, String key, String valueName, int wow64) 
    throws IllegalArgumentException, IllegalAccessException,
    InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readString(systemRoot, hkey, key, valueName, wow64);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readString(userRoot, hkey, key, valueName, wow64);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Read value(s) and value name(s) form given key 
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
   *               or KEY_WOW64_32KEY to force access to 32-bit registry view,
   *               or KEY_WOW64_64KEY to force access to 64-bit registry view
   * @return the value name(s) plus the value(s)
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static Map<String, String> readStringValues(int hkey, String key, int wow64) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readStringValues(systemRoot, hkey, key, wow64);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readStringValues(userRoot, hkey, key, wow64);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Read the value name(s) from a given key
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
   *               or KEY_WOW64_32KEY to force access to 32-bit registry view,
   *               or KEY_WOW64_64KEY to force access to 64-bit registry view
   * @return the value name(s)
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static List<String> readStringSubKeys(int hkey, String key, int wow64) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      return readStringSubKeys(systemRoot, hkey, key, wow64);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      return readStringSubKeys(userRoot, hkey, key, wow64);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Create a key
   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
   * @param key
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void createKey(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int [] ret;
    if (hkey == HKEY_LOCAL_MACHINE) {
      ret = createKey(systemRoot, hkey, key);
      regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
    }
    else if (hkey == HKEY_CURRENT_USER) {
      ret = createKey(userRoot, hkey, key);
      regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
    if (ret[1] != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
    }
  }

  /**
   * Write a value in a given key/value name
   * @param hkey
   * @param key
   * @param valueName
   * @param value
   * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
   *               or KEY_WOW64_32KEY to force access to 32-bit registry view,
   *               or KEY_WOW64_64KEY to force access to 64-bit registry view
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void writeStringValue
    (int hkey, String key, String valueName, String value, int wow64) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    if (hkey == HKEY_LOCAL_MACHINE) {
      writeStringValue(systemRoot, hkey, key, valueName, value, wow64);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      writeStringValue(userRoot, hkey, key, valueName, value, wow64);
    }
    else {
      throw new IllegalArgumentException("hkey=" + hkey);
    }
  }

  /**
   * Delete a given key
   * @param hkey
   * @param key
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void deleteKey(int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int rc = -1;
    if (hkey == HKEY_LOCAL_MACHINE) {
      rc = deleteKey(systemRoot, hkey, key);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      rc = deleteKey(userRoot, hkey, key);
    }
    if (rc != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
    }
  }

  /**
   * delete a value from a given key/value name
   * @param hkey
   * @param key
   * @param value
   * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
   *               or KEY_WOW64_32KEY to force access to 32-bit registry view,
   *               or KEY_WOW64_64KEY to force access to 64-bit registry view
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static void deleteValue(int hkey, String key, String value, int wow64) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int rc = -1;
    if (hkey == HKEY_LOCAL_MACHINE) {
      rc = deleteValue(systemRoot, hkey, key, value, wow64);
    }
    else if (hkey == HKEY_CURRENT_USER) {
      rc = deleteValue(userRoot, hkey, key, value, wow64);
    }
    if (rc != REG_SUCCESS) {
      throw new IllegalArgumentException("rc=" + rc + "  key=" + key + "  value=" + value);
    }
  }

  //========================================================================
  private static int deleteValue(Preferences root, int hkey, String key, String value, int wow64)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS | wow64)
    });
    if (handles[1] != REG_SUCCESS) {
      return handles[1];  // can be REG_NOTFOUND, REG_ACCESSDENIED
    }
    int rc =((Integer) regDeleteValue.invoke(root, new Object[] { 
          new Integer(handles[0]), toCstr(value) 
          })).intValue();
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return rc;
  }

  //========================================================================
  private static int deleteKey(Preferences root, int hkey, String key) 
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int rc =((Integer) regDeleteKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key)
    })).intValue();
    return rc;  // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
  }

  //========================================================================
  private static String readString(Preferences root, int hkey, String key, String value, int wow64)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64)
    });
    if (handles[1] != REG_SUCCESS) {
      return null; 
    }
    byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
        new Integer(handles[0]), toCstr(value)
    });
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return (valb != null ? new String(valb).trim() : null);
  }

  //========================================================================
  private static Map<String,String> readStringValues(Preferences root, int hkey, String key, int wow64)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    HashMap<String, String> results = new HashMap<String,String>();
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64)
    });
    if (handles[1] != REG_SUCCESS) {
      return null;
    }
    int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] {
        new Integer(handles[0])
    });

    int count  = info[2]; // count  
    int maxlen = info[3]; // value length max
    for(int index=0; index<count; index++)  {
      byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
          new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)
      });
      String value = readString(hkey, key, new String(name), wow64);
      results.put(new String(name).trim(), value);
    }
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return results;
  }

  //========================================================================
  private static List<String> readStringSubKeys(Preferences root, int hkey, String key, int wow64)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    List<String> results = new ArrayList<String>();
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_READ | wow64) 
        });
    if (handles[1] != REG_SUCCESS) {
      return null;
    }
    int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] {
        new Integer(handles[0])
    });

    int count  = info[0]; // Fix: info[2] was being used here with wrong results. Suggested by davenpcj, confirmed by Petrucio
    int maxlen = info[3]; // value length max
    for(int index=0; index<count; index++)  {
      byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
          new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)
          });
      results.add(new String(name).trim());
    }
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
    return results;
  }

  //========================================================================
  private static int [] createKey(Preferences root, int hkey, String key)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    return (int[]) regCreateKeyEx.invoke(root, new Object[] {
      new Integer(hkey), toCstr(key)
    });
  }

  //========================================================================
  private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value, int wow64)
    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException 
  {
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS | wow64)
    });
    regSetValueEx.invoke(root, new Object[] { 
          new Integer(handles[0]), toCstr(valueName), toCstr(value) 
          }); 
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
  }

  //========================================================================
  // utility
  private static byte[] toCstr(String str) {
    byte[] result = new byte[str.length() + 1];

    for (int i = 0; i < str.length(); i++) {
      result[i] = (byte) str.charAt(i);
    }
    result[str.length()] = 0;
    return result;
  }
}

хорошая работа. Это решение помогает, если вы хотите получить доступ к 32-битному реестру в 64-битной JRE и наоборот
MyPasswordIsLasercats

Таким образом, readString в основном читает соответствующие значения, как только я даю в пути? Например, при вызове этого метода я должен вставить hkey туда, где я хочу, чтобы чтение было справа?
Скарл

@Petrucio Этот код не работает в среде Linux (CentOS7). Пожалуйста, дайте мне любое другое решение.
Четан Бхагат

@ChetanBhagat Извините, приятель, я некоторое время не занимаюсь разработкой Java, а тем более в Linux. Ты должен найти свое собственное решение.
Петруччо

Под Java11 (и , возможно , раньше) некоторые из типов должны быть изменены с , intчтобы longсделать эту работу снова.
Хендрик

23

Я сделал это перед использованием 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);
    }
}

}

8
Это не поддерживает 64 бит! Парню, который написал это, нужна ваша помощь, чтобы добавить поддержку 64-битной JVM. sourceforge.net/tracker/…
Cal

1
Это также не доступно на Центральном Maven.
Пупено

21

Да, используя API java.util.Preferences, так как его реализация Windows использует Реестр в качестве бэкэнда.

В конце концов, это зависит от того, что вы хотите сделать: сохранение настроек для вашего приложения - это то, что настройки делают просто великолепно. Если вы действительно хотите изменить разделы реестра, не связанные с вашим приложением, вам понадобится некоторое приложение JNI, как описано Марком (бесстыдная кража здесь):

Из быстрого Google: Проверьте WinPack для JNIWrapper. Он имеет полную поддержку доступа к реестру Windows, включая чтение и запись.

В качестве примера в демоверсии WinPack реализована программа просмотра реестра.

Проверьте на http://www.teamdev.com/jniwrapper/winpack/#registry_access

И...

Есть также попробовать JNIRegistry @ http://www.trustice.com/java/jnireg/

Существует также возможность вызова внешнего приложения, которое отвечает за чтение / запись реестра.


3
Итак, как можно редактировать HKEY_CLASSES_ROOT с помощью API настроек?
Винко Врсалович

2
Для этого вам понадобится приложение JNI
Epaga

11

Из быстрого Google:

Проверьте WinPack для JNIWrapper. Он имеет полную поддержку доступа к реестру Windows, включая чтение и запись.

В качестве примера в демоверсии WinPack реализована программа просмотра реестра.

Проверьте на http://www.teamdev.com/jniwrapper/winpack/#registry_access

И...

Есть также попробовать JNIRegistry @ http://www.trustice.com/java/jnireg/

Существует также возможность вызова внешнего приложения, которое отвечает за чтение / запись реестра.


8

Вот модифицированная версия решения Олега. Я заметил, что в моей системе (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;
  }

}


Даже несмотря на то, что ему почти 10 лет, он по-прежнему один из лучших результатов Google, поэтому совет для будущих пользователей: сделайте два reg-запроса, один с "/ reg: 32" и один с "/ reg: 64", чтобы убедиться, что это работает правильно. Например, Steam для меня 64-битный. Запрашивать HKLM \ SOFTWARE \ Valve \ Steam \ InstallPath не удается, если я не добавлю / reg: 32, потому что «настоящий» ключ - это HKLM \ SOFTWARE \ WOW6432Node \ Valve ..
Kadser

Исправление: пар 32 бит, мой ОС 64 бит. Извините, слишком поздно для редактирования
Kadser

7

Благодаря оригинальному сообщению. Я повторно создал этот служебный класс и обнаружил недостатки, которые были у него ранее, подумал, что это может помочь другим, поэтому размещать здесь. Я также добавил несколько дополнительных утилитарных методов. Теперь он может читать любой файл в реестре 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 и т. Д. Они все такие же, как я их получил.


Когда я записываю реестр в HKEY_LOCAL_MACHINE, ошибка отображается как java.lang.IllegalArgumentException: ключ rc = 5 = ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \ rgagnon.com \ aa. WinRegistry.createKey (WinRegistry.java:157). как это решить.
Kyaw Zin Htun

пожалуйста, прочитайте важную заметку в последнем, я не изменил методы записи реестра, они такие же, как и полученные.
pratapvaibhav19

2
Будьте очень осторожны с этим решением, оно НЕ совпадает с принятым ответом. На самом нижнем уровне он заменяет вызов класса Preference оболочкой на команду «reg query», но выглядит достаточно похоже на принятый ответ, что вы можете не сразу понять это.
Билл К

6

Вероятно, лучший способ записи в реестр - использовать 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];
    }
}

5

Как было отмечено, API настроек использует реестр для хранения настроек, но не может использоваться для доступа ко всему реестру.

Однако пират Дэвид Крофт выяснил, что в реализации Sun Preferences API можно использовать методы для чтения реестра Windows из Java без JNI . В этом есть некоторые опасности, но на это стоит посмотреть.



4

Подход API настроек не дает вам доступа ко всем веткам реестра. На самом деле, он дает вам доступ только к тому месту, где Preferences API хранит свои предпочтения. Это не универсальный API обработки реестра, как в .NET

Как показывает Марк, для чтения / записи каждого ключа, я думаю, JNI или внешний инструмент был бы подходом.


Я ненавижу то, что API настроек на самом деле является настройками самой Java. Я хотел бы, чтобы это было более общим, как вы сказали.

3

Вы можете попробовать WinRun4J . Это средство запуска и запуска Windows, а также библиотека для доступа к реестру.

(Кстати, я работаю над этим проектом, поэтому дайте мне знать, если у вас есть какие-либо вопросы)


3

Мое предыдущее изменение в ответе @ David было отклонено. Вот некоторая полезная информация об этом.

Эта «магия» работает, потому что Sun реализует Preferencesкласс для Windows как часть JDK, но это частный пакет . Части реализации используют JNI.

Реализация выбирается во время выполнения с использованием заводского метода здесь: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/prefs/Preferences.java# Preferences.0factory

Реальный вопрос: почему OpenJDK не предоставляет этот API публично?


2

java.util.prefsПакет предоставляет способ для приложений для хранения и извлечения пользовательских и системных настроек и конфигураций данных. Эти данные предпочтения будут постоянно храниться в зависимой от реализации резервной копии. Например, в операционной системе Windows в будет храниться в реестре Windows.

Для записи и чтения этих данных мы используем java.util.prefs.Preferencesкласс. Ниже код показывает, как читать и писать в HKCUи HKLMв реестре.

import java.util.prefs.Preferences;

public class RegistryDemo {
    public static final String PREF_KEY = "org.username";
    public static void main(String[] args) {
        //
        // Write Preferences information to HKCU (HKEY_CURRENT_USER),
        // HKCU\Software\JavaSoft\Prefs\org.username
        //
        Preferences userPref = Preferences.userRoot();
        userPref.put(PREF_KEY, "xyz");

        //
        // Below we read back the value we've written in the code above.
        //
        System.out.println("Preferences = "
                + userPref.get(PREF_KEY, PREF_KEY + " was not found."));

        //
        // Write Preferences information to HKLM (HKEY_LOCAL_MACHINE),
        // HKLM\Software\JavaSoft\Prefs\org.username
        //
        Preferences systemPref = Preferences.systemRoot();
        systemPref.put(PREF_KEY, "xyz");

        //
        // Read back the value we've written in the code above.
        //
        System.out.println("Preferences = "
                + systemPref.get(PREF_KEY, PREF_KEY + " was not found."));
    }
}

1

Еще одна библиотека ...

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

Этот запускает reg.exe под крышками, чтение / запись во временные файлы. Я не заканчивал тем, что использовал это, но это похоже на довольно полную реализацию. Если бы я использовал его, я мог бы погрузиться и добавить немного лучшего управления дочерними процессами.


Не предоставляет нативную реализацию, а просто вызывает regedit.exe.
Даниил

0

Хотя это довольно старое, но я думаю, что лучшая утилита для использования на платформе Windows будет regini:

Один вызов для обработки:

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

сделает всю магию. Я пробовал это, делая jar как службу Windows, используя servany.exe, который требует внесения изменений в реестр для добавления аргументов javaw.exe, и он работает отлично. Возможно, вам захочется прочитать это: http://support.microsoft.com/kb/264584


0

Это было сумасшествие ... Я взял код из одного из постов здесь, не смог увидеть еще 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;
    }
}

ВНИМАНИЕ: ЭТО НЕ ЧИТАЕТ НИЧЕГО, НО СТРАХ !!!!!



-1

При этом используются те же внутренние API-интерфейсы Java, что и в ответе Дэвида , но я полностью переписал его. Теперь он короче и приятнее в использовании. Я также добавил поддержку HKEY_CLASSES_ROOT и других ульев. Однако он по-прежнему имеет некоторые другие ограничения (например, отсутствие поддержки DWORD и поддержки Unicode), которые обусловлены базовым API и, к сожалению, неизбежны при таком подходе. Тем не менее, если вам нужно только базовое чтение / запись строк и вы не хотите загружать собственную DLL, это удобно.

Я уверен, что вы можете понять, как его использовать.

Всеобщее достояние. Радоваться, веселиться.

import java.util.*;
import java.lang.reflect.Method;

/**
 * Simple registry access class implemented using some private APIs
 * in java.util.prefs. It has no other prerequisites.
 */
public final class WindowsRegistry {
    /**
     * Tells if the Windows registry functions are available.
     * (They will not be available when not running on Windows, for example.)
     */
    public static boolean isAvailable() {
        return initError == null;
    }



    /** Reads a string value from the given key and value name. */
    public static String readValue(String keyName, String valueName) {
        try (Key key = Key.open(keyName, KEY_READ)) {
            return fromByteArray(invoke(regQueryValueEx, key.handle, toByteArray(valueName)));
        }
    }



    /** Returns a map of all the name-value pairs in the given key. */
    public static Map<String,String> readValues(String keyName) {
        try (Key key = Key.open(keyName, KEY_READ)) {
            int[] info = invoke(regQueryInfoKey, key.handle);
            checkError(info[INFO_ERROR_CODE]);
            int count = info[INFO_COUNT_VALUES];
            int maxlen = info[INFO_MAX_VALUE_LENGTH] + 1;
            Map<String,String> values = new HashMap<>();
            for (int i = 0; i < count; i++) {
                String valueName = fromByteArray(invoke(regEnumValue, key.handle, i, maxlen));
                values.put(valueName, readValue(keyName, valueName));
            }
            return values;
        }
    }



    /** Returns a list of the names of all the subkeys of a key. */
    public static List<String> readSubkeys(String keyName) {
        try (Key key = Key.open(keyName, KEY_READ)) {
            int[] info = invoke(regQueryInfoKey, key.handle);
            checkError(info[INFO_ERROR_CODE]);
            int count = info[INFO_COUNT_KEYS];
            int maxlen = info[INFO_MAX_KEY_LENGTH] + 1;
            List<String> subkeys = new ArrayList<>(count);
            for (int i = 0; i < count; i++) {
                subkeys.add(fromByteArray(invoke(regEnumKeyEx, key.handle, i, maxlen)));
            }
            return subkeys;
        }
    }



    /** Writes a string value with a given key and value name. */
    public static void writeValue(String keyName, String valueName, String value) {
        try (Key key = Key.open(keyName, KEY_WRITE)) {
            checkError(invoke(regSetValueEx, key.handle, toByteArray(valueName), toByteArray(value)));
        }
    }



    /** Deletes a value within a key. */
    public static void deleteValue(String keyName, String valueName) {
        try (Key key = Key.open(keyName, KEY_WRITE)) {
            checkError(invoke(regDeleteValue, key.handle, toByteArray(valueName)));
        }
    }



    /**
     * Deletes a key and all values within it. If the key has subkeys, an
     * "Access denied" error will be thrown. Subkeys must be deleted separately.
     */
    public static void deleteKey(String keyName) {
        checkError(invoke(regDeleteKey, keyParts(keyName)));
    }



    /**
     * Creates a key. Parent keys in the path will also be created if necessary.
     * This method returns without error if the key already exists.
     */
    public static void createKey(String keyName) {
        int[] info = invoke(regCreateKeyEx, keyParts(keyName));
        checkError(info[INFO_ERROR_CODE]);
        invoke(regCloseKey, info[INFO_HANDLE]);
    }



    /**
     * The exception type that will be thrown if a registry operation fails.
     */
    public static class RegError extends RuntimeException {
        public RegError(String message, Throwable cause) {
            super(message, cause);
        }
    }





    // *************
    // PRIVATE STUFF
    // *************

    private WindowsRegistry() {}


    // Map of registry hive names to constants from winreg.h
    private static final Map<String,Integer> hives = new HashMap<>();
    static {
        hives.put("HKEY_CLASSES_ROOT",   0x80000000); hives.put("HKCR", 0x80000000);
        hives.put("HKEY_CURRENT_USER",   0x80000001); hives.put("HKCU", 0x80000001);
        hives.put("HKEY_LOCAL_MACHINE",  0x80000002); hives.put("HKLM", 0x80000002);
        hives.put("HKEY_USERS",          0x80000003); hives.put("HKU",  0x80000003);
        hives.put("HKEY_CURRENT_CONFIG", 0x80000005); hives.put("HKCC", 0x80000005);
    }


    // Splits a path such as HKEY_LOCAL_MACHINE\Software\Microsoft into a pair of
    // values used by the underlying API: An integer hive constant and a byte array
    // of the key path within that hive.
    private static Object[] keyParts(String fullKeyName) {
        int x = fullKeyName.indexOf('\\');
        String hiveName = x >= 0 ? fullKeyName.substring(0, x)  : fullKeyName;
        String keyName  = x >= 0 ? fullKeyName.substring(x + 1) : "";
        Integer hkey = hives.get(hiveName);
        if (hkey == null) throw new RegError("Unknown registry hive: " + hiveName, null);
        return new Object[] { hkey, toByteArray(keyName) };
    }


    // Type encapsulating a native handle to a registry key
    private static class Key implements AutoCloseable {
        final int handle;

        private Key(int handle) {
            this.handle = handle;
        }

        static Key open(String keyName, int accessMode) {
            Object[] keyParts = keyParts(keyName);
            int[] ret = invoke(regOpenKey, keyParts[0], keyParts[1], accessMode);
            checkError(ret[INFO_ERROR_CODE]);
            return new Key(ret[INFO_HANDLE]);
        }

        @Override
        public void close() {
            invoke(regCloseKey, handle);
        }
    }


    // Array index constants for results of regOpenKey, regCreateKeyEx, and regQueryInfoKey
    private static final int
        INFO_HANDLE = 0,
        INFO_COUNT_KEYS = 0,
        INFO_ERROR_CODE = 1,
        INFO_COUNT_VALUES = 2,
        INFO_MAX_KEY_LENGTH = 3,
        INFO_MAX_VALUE_LENGTH = 4;


    // Registry access mode constants from winnt.h
    private static final int
        KEY_READ = 0x20019,
        KEY_WRITE = 0x20006;


    // Error constants from winerror.h
    private static final int
        ERROR_SUCCESS = 0,
        ERROR_FILE_NOT_FOUND = 2,
        ERROR_ACCESS_DENIED = 5;

    private static void checkError(int e) {
        if (e == ERROR_SUCCESS) return;
        throw new RegError(
            e == ERROR_FILE_NOT_FOUND ? "Key not found" :
            e == ERROR_ACCESS_DENIED ? "Access denied" :
            ("Error number " + e), null);
    }


    // Registry access methods in java.util.prefs.WindowsPreferences
    private static final Method
        regOpenKey = getMethod("WindowsRegOpenKey", int.class, byte[].class, int.class),
        regCloseKey = getMethod("WindowsRegCloseKey", int.class),
        regQueryValueEx = getMethod("WindowsRegQueryValueEx", int.class, byte[].class),
        regQueryInfoKey = getMethod("WindowsRegQueryInfoKey", int.class),
        regEnumValue = getMethod("WindowsRegEnumValue", int.class, int.class, int.class),
        regEnumKeyEx = getMethod("WindowsRegEnumKeyEx", int.class, int.class, int.class),
        regSetValueEx = getMethod("WindowsRegSetValueEx", int.class, byte[].class, byte[].class),
        regDeleteValue = getMethod("WindowsRegDeleteValue", int.class, byte[].class),
        regDeleteKey = getMethod("WindowsRegDeleteKey", int.class, byte[].class),
        regCreateKeyEx = getMethod("WindowsRegCreateKeyEx", int.class, byte[].class);

    private static Throwable initError;

    private static Method getMethod(String methodName, Class<?>... parameterTypes) {
        try {
            Method m = java.util.prefs.Preferences.systemRoot().getClass()
                .getDeclaredMethod(methodName, parameterTypes);
            m.setAccessible(true);
            return m;
        } catch (Throwable t) {
            initError = t;
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    private static <T> T invoke(Method method, Object... args) {
        if (initError != null)
            throw new RegError("Registry methods are not available", initError);
        try {
            return (T)method.invoke(null, args);
        } catch (Exception e) {
            throw new RegError(null, e);
        }
    }


    // Conversion of strings to/from null-terminated byte arrays.
    // There is no support for Unicode; sorry, this is a limitation
    // of the underlying methods that Java makes available.
    private static byte[] toByteArray(String str) {
        byte[] bytes = new byte[str.length() + 1];
        for (int i = 0; i < str.length(); i++)
            bytes[i] = (byte)str.charAt(i);
        return bytes;
    }

    private static String fromByteArray(byte[] bytes) {
        if (bytes == null) return null;
        char[] chars = new char[bytes.length - 1];
        for (int i = 0; i < chars.length; i++)
            chars[i] = (char)((int)bytes[i] & 0xFF);
        return new String(chars);
    }
}

Однажды Java будет иметь встроенный интерфейс сторонних функций для легкого доступа к нативным API, и этот вид взлома будет ненужным.


-2

В ответ Дэвид ответ - я хотел бы сделать некоторые улучшения:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;

public class WinRegistry {

    public static final int HKEY_CURRENT_USER = 0x80000001,
            HKEY_LOCAL_MACHINE = 0x80000002,
            REG_SUCCESS = 0,
            REG_NOTFOUND = 2,
            REG_ACCESSDENIED = 5,
            KEY_ALL_ACCESS = 0xf003f,
            KEY_READ = 0x20019;
    private static final Preferences userRoot = Preferences.userRoot(),
            systemRoot = Preferences.systemRoot();
    private static final Class<? extends Preferences> userClass = userRoot.getClass();
    private static Method regOpenKey,
            regCloseKey,
            regQueryValueEx,
            regEnumValue,
            regQueryInfoKey,
            regEnumKeyEx,
            regCreateKeyEx,
            regSetValueEx,
            regDeleteKey,
            regDeleteValue;

    static {
        try {
            (regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", new Class[]{int.class, byte[].class, int.class})).setAccessible(true);
            (regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", new Class[]{int.class})).setAccessible(true);
            (regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx", new Class[]{int.class, byte[].class})).setAccessible(true);
            (regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue", new Class[]{int.class, int.class, int.class})).setAccessible(true);
            (regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1", new Class[]{int.class})).setAccessible(true);
            (regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", new Class[]{int.class, int.class, int.class})).setAccessible(true);
            (regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[]{int.class, byte[].class})).setAccessible(true);
            (regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[]{int.class, byte[].class, byte[].class})).setAccessible(true);
            (regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[]{int.class, byte[].class})).setAccessible(true);
            (regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[]{int.class, byte[].class})).setAccessible(true);
        } catch (NoSuchMethodException | SecurityException ex) {
            Logger.getLogger(WinRegistry.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 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 {

        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readString(systemRoot, hkey, key, valueName);
            case HKEY_CURRENT_USER:
                return readString(userRoot, hkey, key, valueName);
            default:
                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 {

        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readStringValues(systemRoot, hkey, key);
            case HKEY_CURRENT_USER:
                return readStringValues(userRoot, hkey, key);
            default:
                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 {

        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                return readStringSubKeys(systemRoot, hkey, key);
            case HKEY_CURRENT_USER:
                return readStringSubKeys(userRoot, hkey, key);
            default:
                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;
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                ret = createKey(systemRoot, hkey, key);
                regCloseKey.invoke(systemRoot, new Object[]{ret[0]});
                break;
            case HKEY_CURRENT_USER:
                ret = createKey(userRoot, hkey, key);
                regCloseKey.invoke(userRoot, new Object[]{ret[0]});
                break;
            default:
                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 {

        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                writeStringValue(systemRoot, hkey, key, valueName, value);
                break;
            case HKEY_CURRENT_USER:
                writeStringValue(userRoot, hkey, key, valueName, value);
                break;
            default:
                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;
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                rc = deleteKey(systemRoot, hkey, key);
                break;
            case 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;
        switch (hkey) {
            case HKEY_LOCAL_MACHINE:
                rc = deleteValue(systemRoot, hkey, key, value);
                break;
            case 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[]{hkey, toCstr(key), 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[]{handles[0], toCstr(value)}));
        regCloseKey.invoke(root, new Object[]{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[]{hkey, toCstr(key)}));
        return rc;  //Can be 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[]{hkey, toCstr(key), KEY_READ});
        if (handles[1] != REG_SUCCESS) {
            return null;
        }
        byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[]{handles[0], toCstr(value)});
        regCloseKey.invoke(root, new Object[]{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<>();
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{hkey, toCstr(key), KEY_READ});
        if (handles[1] != REG_SUCCESS) {
            return null;
        }
        int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[]{handles[0]});

        int count = info[0]; //Count  
        int maxlen = info[3]; //Max value length
        for (int index = 0; index < count; index++) {
            byte[] name = (byte[]) regEnumValue.invoke(root, new Object[]{handles[0], index, maxlen + 1});
            String value = readString(hkey, key, new String(name));
            results.put(new String(name).trim(), value);
        }
        regCloseKey.invoke(root, new Object[]{handles[0]});
        return results;
    }

    private static List<String> readStringSubKeys(Preferences root, int hkey, String key) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {

        List<String> results = new ArrayList<>();
        int[] handles = (int[]) regOpenKey.invoke(root, new Object[]{hkey, toCstr(key), KEY_READ});
        if (handles[1] != REG_SUCCESS) {
            return null;
        }
        int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[]{handles[0]});

        int count = info[0];//Count
        int maxlen = info[3]; //Max value length
        for (int index = 0; index < count; index++) {
            byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[]{handles[0], index, maxlen + 1});
            results.add(new String(name).trim());
        }
        regCloseKey.invoke(root, new Object[]{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[]{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[]{hkey, toCstr(key), KEY_ALL_ACCESS});
        regSetValueEx.invoke(root, new Object[]{handles[0], toCstr(valueName), toCstr(value)});
        regCloseKey.invoke(root, new Object[]{handles[0]});
    }

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

-2

Вы можете выполнить эти команды "REG QUERY", используя код Java .

Попробуйте выполнить это из командной строки и выполнить команду из кода Java.

HKEY_LOCAL_MACHINE "ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \ Microsoft \ Windows NT \ CurrentVersion"

Для поиска таких деталей, как версия продукта и т. Д. Используйте / v amd "имя".

HKEY_LOCAL_MACHINE "ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \ Microsoft \ Windows NT \ CurrentVersion" / v "ProductName"


Перейдите по URL-адресу: - stackoverflow.com/questions/7112259/… попробуйте выполнить «REG QUERY» из этого кода.
Палак Нагар

-5

Я предпочитаю использовать класс java.util.prefs.Preferences .

Простой пример будет

// Write Operation
Preferences p = Preferences.userRoot();
p.put("key","value"); 
// also there are various other methods such as putByteArray(), putDouble() etc.
p.flush();
//Read Operation
Preferences p = Preferences.userRoot();
String value = p.get("key");

19
Это на самом деле не отвечает на вопрос.
jplandrain
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.