Lesen/Schreiben in die Windows-Registrierung mit Java

Lesezeit: 25 Minuten

Wie ist es möglich, mit Java in die Windows-Registrierung zu lesen/schreiben?

  • Ich würde sagen, der einfachste Weg ist die Verwendung com.sun.deploy.association.utility.WinRegistryWrapper

    – Jire

    18. Januar 2017 um 6:42 Uhr

  • @Jire Das ist in jeder Hinsicht besser als die akzeptierte Lösung, außer dass Sie die “deploy.jar” aus Ihrer Java-Installation in das Projekt aufnehmen müssen – sie wird nicht automatisch aufgenommen. Es leidet auch unter dem gleichen großen Problem – es kann nur mit Strings umgehen (nicht einmal mit mehreren Strings). Sie könnten es als neue Antwort mit einigen Beispielanwendungen hinzufügen. Wenn Sie nicht genug Repräsentanten haben, um diese Frage zu posten, lassen Sie es mich wissen und ich werde es für Sie tun.

    – Bill K

    9. Februar 2017 um 23:17 Uhr


LesenSchreiben in die Windows Registrierung mit Java
David

Ich weiß, dass diese Frage alt ist, aber es ist das erste Suchergebnis bei Google zu “Java Read/Write to Registry”. Kürzlich habe ich diesen erstaunlichen Code gefunden, der:

  • Kann in JEDEM Teil der Registrierung lesen/schreiben.
  • VERWENDET KEIN JNI.
  • VERWENDET KEINE DRITTANBIETER/EXTERNE ANWENDUNGEN ZUM ARBEITEN.
  • VERWENDET NICHT DIE WINDOWS-API (direkt)

Dies ist reiner Java-Code.

Es verwendet Reflektion, um zu arbeiten, indem es tatsächlich auf die privaten Methoden in der zugreift java.util.prefs.Preferences Klasse. Die Interna dieser Klasse sind kompliziert, aber die Klasse selbst ist sehr einfach zu benutzen.

Der folgende Code ruft beispielsweise die exakte Windows-Distribution ab aus der Registrierung:

String value = WinRegistry.readString (
    WinRegistry.HKEY_LOCAL_MACHINE,                             //HKEY
   "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",           //Key
   "ProductName");                                              //ValueName
    System.out.println("Windows Distribution = " + value);          

Hier ist die ursprüngliche Klasse. Einfach kopieren und einfügen und es sollte funktionieren:

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

Ursprünglicher Autor: Apache.

Bibliotheksquelle: https://github.com/apache/npanday/tree/trunk/components/dotnet-registry/src/main/java/npanday/registry

  • Dieser Code hat einen kleinen Fehler; readStringSubKeys zum Aufzählen der Unterschlüssel eines Registrierungsschlüssels funktioniert nicht. Ersetzen Sie “int count = info[2]; // count ” in der privaten readStringSubKeys-Funktion mit “int count = info[0]; // count”, und das wird es beheben. Der korrekte Wert kann im reflektierten WindowsPreferences.SUBKEYS_NUMBER-Feld gesehen werden.

    – davenpcj

    10. September 2011 um 19:07 Uhr


  • Wie bekomme ich das, um ein Dword zu lesen? Sein Beispiel funktioniert gut für eine Zeichenfolge, aber ich muss jetzt einen tatsächlichen Wert zum Lesen abrufen. Kommt einfach als null raus.

    – Jerhynsoen

    9. August 2012 um 17:32 Uhr

  • Dies ist unter der Apache-Lizenz lizenziert etwas gegeben Google-Suche.

    – Qix – MONICA WURDE MISSHANDELT

    20. Juli 2013 um 4:23 Uhr

  • Das ist sehr unangenehm – es beinhaltet das Aufrufen nicht-öffentlicher Methoden durch Reflexion. Mit anderen Worten, Sie verlassen den Preferences-Vertrag, wie in den Javadocs beschrieben, und dieser Code kann jedes Mal brechen, wenn Oracle ein neues Update veröffentlicht.

    – Thorbjørn Ravn Andersen

    8. November 2013 um 12:05 Uhr

  • Dieser Code funktioniert möglicherweise nicht mehr in Java 9 weil es die folgende Warnung erzeugt: An illegal reflective access operation has occurred

    – BullyWiiPlaza

    26. August 2017 um 9:01 Uhr


1646694432 996 LesenSchreiben in die Windows Registrierung mit Java
Oleg Ryanboy

Sie brauchen nicht wirklich ein Paket von Drittanbietern. Windows verfügt über ein Reg-Dienstprogramm für alle Registrierungsvorgänge. Um das Befehlsformat zu erhalten, gehen Sie zur DOS-Eingabeaufforderung und geben Sie Folgendes ein:

reg /?

Sie können anrufen Reg durch die Runtime-Klasse:

Runtime.getRuntime().exec("reg <your parameters here>");

Das Bearbeiten von Schlüsseln und das Hinzufügen neuer Schlüssel ist mit dem obigen Befehl unkompliziert. Um die Registrierung zu lesen, müssen Sie Reg‘s Ausgabe, und es ist ein wenig knifflig. Hier ist der Code:

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

  • Oleg, das war wirklich hilfreich, danke! Beachten Sie, dass die Methode readRegistry einen zweiten StreamReader hinzufügen kann, wenn Sie die Ausgabe von process.getErrorStream() lesen möchten. PS es gibt ein zusätzliches Semikolon in “new StringWriter();;”.

    – Andreas Schwan

    24. November 2010 um 23:25 Uhr


  • Dieser Code funktioniert super! Es gibt jedoch ein Problem mit Ihrer Analyse. In meinem Windows 7-Setup gibt es keine Tabulatorzeichen. Der Parsing-Code sollte etwas robuster sein. Ich habe es in meiner Implementierung geändert, um nach dem Schlüssel zu suchen, um sicherzustellen, dass es eine Ausgabe gibt. Ich verwende dann einen regulären Ausdruck, um die Leerzeichen aufzuteilen und die letzte Zeichenfolge zu erhalten. Das sollte immer der Wert für den Schlüssel sein.

    – Mike G

    13. Mai 2011 um 14:21 Uhr

  • Kann mir bitte jemand erklären, warum das Lesen hier multithreaded gemacht wurde?

    – Chani

    24. Februar 2012 um 9:32 Uhr

  • Dies funktioniert gut, außer wenn der Schlüssel Leerzeichen enthält. Um sich davor zu schützen, sollte Process process = Runtime.getRuntime().exec(“reg query ” + ‘”‘+ location + “\” /v \”” + key + “\””);

    – Steve Cohen

    22. September 2012 um 0:23 Uhr

  • Als Antwort auf meinen eigenen Kommentar hat das Problem damit zu tun (stackoverflow.com/questions/252297/…). Grundsätzlich ist reg.exe 64-Bit, während JVM 32-Bit sein kann, sodass sie an verschiedenen Stellen nach dem Schlüssel suchen könnten. Problemumgehung ist, zweimal mit beiden Pfaden anzurufen

    – locka

    20. Januar 2014 um 16:45 Uhr

LesenSchreiben in die Windows Registrierung mit Java
John McCarthy

Nativer Java-Zugriff (JNA) ist ein hervorragendes Projekt für die Arbeit mit nativen Bibliotheken und bietet Unterstützung für die Windows-Registrierung in der Plattformbibliothek (platform.jar) durch Advapi32Util und Advapi32.

Aktualisieren: Hier ist ein Ausschnitt mit einigen Beispielen, wie einfach es ist, JNA zu verwenden, um mit der Windows-Registrierung mit JNA 3.4.1 zu arbeiten.

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

  • Es ist LGPL, das ein Problem sein könnte, wenn es in kommerzieller Software enthalten ist.

    – wie Judo

    11. März 2013 um 16:53 Uhr

  • @kevinarpe “Kommerzielle Lizenzvereinbarungen sind verhandelbar”. Keinen festen Preis zu haben, ist für mich ein Warnsignal.

    – wie Judo

    28. Juni 2013 um 16:00 Uhr


  • Meiner Erfahrung nach kann LGPL-lizenzierte Software mit kommerzieller Software weiterverteilt werden (GPL ist viel restriktiver). Natürlich sollten Sie sich immer mit Ihrer Rechtsabteilung beraten (und haben dies wahrscheinlich bereits getan). Es sieht auch so aus, als ob JNA doppelt lizenziert wird, um die Weiterverteilung unter Apache 2.0 zu ermöglichen, wenn JNA 4.0 veröffentlicht wird (siehe github.com/twall/jna/blob/master/LIZENZ).

    – John McCarthy

    28. Juni 2013 um 16:37 Uhr

  • JNA 4.0+ ist jetzt Apache 2 lizenziert (siehe hier). Ein großes +1 für eine nicht hackige Lösung.

    – Duncan Jones

    23. September 2014 um 7:22 Uhr


  • @ChetanBhagat Ich verstehe nicht, was du zu tun versuchst. Hier geht es um die Arbeit mit Windows-Registrierung, das sehr spezifisch für das Windows-Betriebssystem ist. Es gibt kein Äquivalent zur Registrierung unter Linux. Sehen Linux-Äquivalent zur Windows-Registrierung

    – John McCarthy

    9. April 2019 um 20:41 Uhr

Ich habe den ursprünglich von David geposteten reinen Java-Code erhöht, um den Zugriff auf den 32-Bit-Abschnitt der Registrierung von einer 64-Bit-JVM und umgekehrt zu ermöglichen. Ich glaube nicht, dass eine der anderen Antworten darauf eingeht.

Hier ist es:

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

Ich habe dies vor der Verwendung getan jRegistryKey. Es ist eine LGPL-Java/JNI-Bibliothek, die alles tun kann, was Sie brauchen. Hier ist ein Beispiel dafür, wie ich es verwendet habe, um die Registrierungsbearbeitung über regedit und auch die Option „Ordneroptionen anzeigen“ für mich selbst in Windows über die Registrierung zu aktivieren.

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

}

  • Dies unterstützt kein 64-Bit! Der Typ, der es geschrieben hat, braucht Ihre Hilfe, um 64-Bit-JVM-Unterstützung hinzuzufügen. sourceforge.net/tracker/…

    – Kal

    5. Oktober 2010 um 3:50 Uhr


  • Es ist auch nicht auf Maven Central verfügbar.

    – Puppe

    25. März 2018 um 9:49 Uhr

1646694433 531 LesenSchreiben in die Windows Registrierung mit Java
Gemeinschaft

Ja, mit der java.util.Preferences-API, da die Windows-Implementierung die Registrierung als Backend verwendet.

Am Ende hängt es davon ab, was Sie tun möchten: Das Speichern von Einstellungen für Ihre App ist das, was die Einstellungen einfach großartig machen. Wenn Sie tatsächlich Registrierungsschlüssel ändern möchten, die nichts mit Ihrer App zu tun haben, benötigen Sie eine JNI-App, wie von Mark beschrieben (schamloser Diebstahl hier):

Von einem schnellen Google: Überprüfen Sie das WinPack für JNIWrapper. Es bietet volle Unterstützung für den Zugriff auf die Windows-Registrierung, einschließlich Lesen und Schreiben.

Die WinPack-Demo hat als Beispiel einen Registry Viewer implementiert.

Überprüfen Sie bei http://www.teamdev.com/jniwrapper/winpack/#registry_access

Und…

Es gibt auch versuchen JNIRegistry @ http://www.trustice.com/java/jnireg/

Es besteht auch die Möglichkeit, eine externe App aufzurufen, die für das Lesen/Schreiben der Registry zuständig ist.

  • Dies unterstützt kein 64-Bit! Der Typ, der es geschrieben hat, braucht Ihre Hilfe, um 64-Bit-JVM-Unterstützung hinzuzufügen. sourceforge.net/tracker/…

    – Kal

    5. Oktober 2010 um 3:50 Uhr


  • Es ist auch nicht auf Maven Central verfügbar.

    – Puppe

    25. März 2018 um 9:49 Uhr

1646694434 805 LesenSchreiben in die Windows Registrierung mit Java
wie Judo

Von einem schnellen Google:

Überprüfen Sie das WinPack für JNIWrapper. Es bietet volle Unterstützung für den Zugriff auf die Windows-Registrierung, einschließlich Lesen und Schreiben.

Die WinPack-Demo hat als Beispiel einen Registry Viewer implementiert.

Überprüfen Sie bei
http://www.teamdev.com/jniwrapper/winpack/#registry_access

Und…

Es gibt auch versuchen JNIRegistry @
http://www.trustice.com/java/jnireg/

Es besteht auch die Möglichkeit, eine externe App aufzurufen, die für das Lesen/Schreiben der Registry zuständig ist.

970110cookie-checkLesen/Schreiben in die Windows-Registrierung mit Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy