Чтение / запись в реестр 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.