Java를 사용하여 Windows 레지스트리에 읽기 / 쓰기


323

Java를 사용하여 Windows 레지스트리를 읽고 쓰는 방법은 무엇입니까?


가장 쉬운 방법은 다음과 같습니다.com.sun.deploy.association.utility.WinRegistryWrapper
— Jire

@Jire 프로젝트의 자바 설치에서 "deploy.jar"를 포함시켜야한다는 점을 제외하고는 모든 방법에서 허용되는 솔루션보다 낫습니다. 자동으로 포함되지는 않습니다. 또한 같은 큰 문제로 어려움을 겪습니다. 문자열 (멀티 문자열조차도)을 처리 할 수 ​​없습니다. 일부 예제 사용으로 새 답변으로 추가 할 수 있습니다. 이 질문에 게시 할 담당자가 충분하지 않은 경우 알려 주시면 도와 드리겠습니다.
— Bill K

답변:


328

이 질문이 오래되었다는 것을 알고 있지만 Google에서 "java read / write to registry"에 대한 첫 번째 검색 결과입니다. 최근 에이 놀라운 코드를 발견했습니다.

  • 레지스트리의 모든 부분을 읽고 쓸 수 있습니다.
  • 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가 작동하지 않습니다. private readStringSubKeys 함수의 "int count = info [2]; // count"를 "int count = info [0]; // count"로 바꾸면 문제가 해결됩니다. 반영된 WindowsPreferences.SUBKEYS_NUMBER 필드에서 올바른 값을 볼 수 있습니다.
— davenpcj

11
이 글을 읽으려면 어떻게해야합니까? 그의 샘플은 문자열에 대해서는 잘 작동하지만 지금 읽으려면 실제 값을 가져와야합니다. null로 나옵니다.
— jerhynsoen 17:32에

27
이것은 구글 검색이 주어진 아파치 라이센스하에 라이센스됩니다 .
— Qix-MONICA가 MISTREATED

25
이것은 매우 불쾌합니다. 리플렉션을 통해 비공개 메서드를 호출하는 것과 관련이 있습니다. 즉, Javadocs에 설명 된대로 기본 설정 계약을 벗어나고 있으며이 코드는 Oracle이 새 업데이트를 푸시 할 때마다 중단 될 수 있습니다.
— Thorbjørn Ravn Andersen

11
이 코드 Java 9는 다음과 같은 경고를 생성하기 때문에 더 이상 작동하지 않을 수 있습니다 .An illegal reflective access operation has occurred
— BullyWiiPlaza

132

실제로 타사 패키지가 필요하지 않습니다. Windows에는 모든 레지스트리 작업을위한 reg 유틸리티가 있습니다. 명령 형식을 얻으려면 DOS propmt로 이동하여 다음을 입력하십시오.

reg /?

Runtime 클래스를 통해 reg 를 호출 할 수 있습니다 .

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

위의 명령을 사용하여 키를 편집하고 새 키를 추가하는 것이 간단합니다. 레지스트리를 읽으려면 reg 출력 이 필요 하며 약간 까다 롭습니다. 코드는 다음과 같습니다.

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

/**
 * @author Oleg Ryaboy, based on work by Miguel Enriquez 
 */
public class WindowsReqistry {

    /**
     * 
     * @param location path in the registry
     * @param key registry key
     * @return registry value or null if not found
     */
    public static final String readRegistry(String location, String key){
        try {
            // Run reg query, then read output with StreamReader (internal class)
            Process process = Runtime.getRuntime().exec("reg query " + 
                    '"'+ location + "\" /v " + key);

            StreamReader reader = new StreamReader(process.getInputStream());
            reader.start();
            process.waitFor();
            reader.join();
            String output = reader.getResult();

            // Output has the following format:
            // \n<Version information>\n\n<key>\t<registry type>\t<value>
            if( ! output.contains("\t")){
                    return null;
            }

            // Parse out the value
            String[] parsed = output.split("\t");
            return parsed[parsed.length-1];
        }
        catch (Exception e) {
            return null;
        }

    }

    static class StreamReader extends Thread {
        private InputStream is;
        private StringWriter sw= new StringWriter();

        public StreamReader(InputStream is) {
            this.is = is;
        }

        public void run() {
            try {
                int c;
                while ((c = is.read()) != -1)
                    sw.write(c);
            }
            catch (IOException e) { 
        }
        }

        public String getResult() {
            return sw.toString();
        }
    }
    public static void main(String[] args) {

        // Sample usage
        String value = WindowsReqistry.readRegistry("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\" 
                 + "Explorer\\Shell Folders", "Personal");
        System.out.println(value);
    }
}


2
올렉, 정말 도움이되었습니다! process.getErrorStream ()의 출력을 읽으려면 readRegistry 메소드가 두 번째 StreamReader를 추가 할 수 있습니다. 추신 : "new StringWriter () ;;"에 여분의 세미콜론이 있습니다.
— 앤드류 스완

5
이 코드는 훌륭하게 작동합니다! 그러나 구문 분석에 문제가 있습니다. Windows 7 설정에는 탭 문자가 없습니다. 파싱 ​​코드는 좀 더 강력해야합니다. 출력에서 키가 있는지 확인하기 위해 구현에서 변경했습니다. 그런 다음 정규 표현식을 사용하여 공백을 나누고 마지막 문자열을 가져옵니다. 항상 키의 값이어야합니다.
— Mike G

4
누구든지 왜 독서가 여기에서 다중 스레드로 만들어 졌는지 설명해 주시겠습니까?
— Chani

키에 공백이있는 경우를 제외하고는 잘 작동합니다. 이를 방지하려면 프로세스 프로세스 = Runtime.getRuntime (). exec ( "reg query"+ ' "'+ location +"\ "/ v \" "+ key +"\ "");
— Steve Cohen

4
내 의견에 대한 대답으로 문제는 이것과 관련이 있습니다 ( stackoverflow.com/questions/252297/… ). 기본적으로 reg.exe는 64 비트 인 반면 JVM은 32 비트 일 수 있으므로 키의 다른 위치를 찾을 수 있습니다. 해결 방법은 두 경로로 두 번 호출하는 것입니다
— 라카

72

JNA (Java Native Access) 는 기본 라이브러리 작업을위한 훌륭한 프로젝트이며 Advapi32Util 및 Advapi32를 통해 플랫폼 라이브러리 (platform.jar)에서 Windows 레지스트리를 지원합니다 .

업데이트 : 다음은 JNA 3.4.1을 사용하여 JNA를 사용하여 Windows 레지스트리를 사용하는 것이 얼마나 쉬운 지에 대한 예제입니다.

import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;

public class WindowsRegistrySnippet {
    public static void main(String[] args) {
        // Read a string
        String productName = Advapi32Util.registryGetStringValue(
            WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
        System.out.printf("Product Name: %s\n", productName);

        // Read an int (& 0xFFFFFFFFL for large unsigned int)
        int timeout = Advapi32Util.registryGetIntValue(
            WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", "ShutdownWarningDialogTimeout");
        System.out.printf("Shutdown Warning Dialog Timeout: %d (%d as unsigned long)\n", timeout, timeout & 0xFFFFFFFFL);

        // Create a key and write a string
        Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow");
        Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow", "url", "http://stackoverflow.com/a/6287763/277307");

        // Delete a key
        Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "SOFTWARE\\StackOverflow");
    }
}

6
상용 소프트웨어에 포함시킬 수있는 문제는 LGPL입니다.
— likejudo

1
@likejiujitsu : 저자는 GitHub 페이지에 따라 상업용 라이센스를 기꺼이 판매합니다.
— kevinarpe 2016 년

1
@kevinarpe "상업용 라이센스 계약은 협상 가능합니다". 정해진 가격이 없다는 것은 저에게 붉은 깃발입니다.
— likejudo

3
내 경험상 LGPL 라이센스 소프트웨어는 상용 소프트웨어와 함께 재배포 할 수 있습니다 (GPL은 훨씬 제한적 임). 물론, 항상 법무 부서와 상담해야합니다. 또한 JNA 4.0이 릴리스 될 때 Apache 2.0에서 재배포 할 수 있도록 JNA가 이중 라이센스를받는 것처럼 보입니다 ( github.com/twall/jna/blob/master/LICENSE 참조 ).
— John McCarthy

8
JNA 4.0 이상은 이제 Apache 2 라이센스가 부여되었습니다 ( 여기 참조 ). 해킹되지 않은 솔루션의 경우 큰 +1입니다.
— Duncan Jones

26

64 비트 JVM에서 레지스트리의 32 비트 섹션을 사용할 수 있도록 David가 원래 게시 한 Pure Java 코드를 증가 시켰으며 그 반대도 마찬가지입니다. 나는 다른 대답이 이것을 해결한다고 생각하지 않습니다.

여기있어:

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

잘 했어. 이 솔루션은 64 비트 JRE에서 32 비트 레지스트리에 액세스하거나 그 반대로
— MyPasswordIsLasercats

그래서 readString은 기본적으로 경로에 제공하면 해당 값을 읽습니까? 이 메소드를 호출 할 때와 같이 읽기를 올바르게 시작하려는 위치에 hkey 삽입을해야합니까?
— Scarl

@Petrucio이 코드는 Linux (CentOS7) 환경에서 작동하지 않습니다. 다른 해결책을 알려주세요.
— Chetan Bhagat

@ChetanBhagat 죄송합니다. Linux에서 Java를 한동안 개발하지 않고 있습니다. 자신 만의 해결책을 찾아야합니다.
— Petrucio

Java11에서 (아마도 이전) 유형 중 일부는 변경 될 필요가 int에 long다시이 작업을 할 수 있습니다.
— Hendrik

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 Central에서는 사용할 수 없습니다.
— pupeno

21

그렇습니다. java.util.Preferences API를 사용하는 이유는 Windows 구현에서 레지스트리를 백엔드로 사용하기 때문입니다.

결국 그것은 당신이하고 싶은 일에 달려 있습니다 : 앱의 환경 설정을 저장하는 것이 환경 설정이 잘하는 것입니다. 앱과 관련이없는 레지스트리 키를 실제로 변경하려면 Mark (부끄러운 도용)에서 설명한대로 일부 JNI 앱이 필요합니다.

빠른 구글에서 : WinPack for JNIWrapper를 확인하십시오. 읽기 및 쓰기를 포함한 전체 Windows 레지스트리 액세스 지원이 있습니다.

WinPack 데모에는 레지스트리 뷰어가 예로 들어 있습니다.

http://www.teamdev.com/jniwrapper/winpack/#registry_access 에서 확인하십시오 .

과...

JNIRegistry @ http://www.trustice.com/java/jnireg/ 도 시도 하십시오.

레지스트리 읽기 / 쓰기를 담당하는 외부 앱을 호출하는 옵션도 있습니다.


3
그렇다면 Preferences API로 HKEY_CLASSES_ROOT를 어떻게 편집합니까?
— Vinko Vrsalovic

2
이를 위해서는 JNI 앱이 필요합니다
— Epaga

11

빠른 구글에서 :

JNIWrapper 용 WinPack을 확인하십시오. 읽기 및 쓰기를 포함한 전체 Windows 레지스트리 액세스 지원이 있습니다.

WinPack 데모에는 레지스트리 뷰어가 예로 들어 있습니다.

http://www.teamdev.com/jniwrapper/winpack/#registry_access 에서 확인하십시오 .

과...

JNIRegistry @ http://www.trustice.com/java/jnireg/ 도 시도 하십시오.

레지스트리 읽기 / 쓰기를 담당하는 외부 앱을 호출하는 옵션도 있습니다.


8

다음은 수정 된 Oleg 솔루션 버전입니다. 내 시스템 (Windows Server 2003)에서 "reg query"의 출력이 탭 ( '\ t')으로 구분되지 않고 4 개의 공백으로 구분됩니다.

스레드가 필요하지 않기 때문에 솔루션을 단순화했습니다.

public static final String readRegistry(String location, String key)
{
  try
  {
      // Run reg query, then read output with StreamReader (internal class)
      Process process = Runtime.getRuntime().exec("reg query " + 
              '"'+ location + "\" /v " + key);

      InputStream is = process.getInputStream();
      StringBuilder sw = new StringBuilder();

      try
      {
         int c;
         while ((c = is.read()) != -1)
             sw.append((char)c);
      }
      catch (IOException e)
      { 
      }

      String output = sw.toString();

      // Output has the following format:
      // \n<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-queries를 작성하십시오. 하나는 "/ reg : 32"이고 다른 하나는 "/ reg : 64"입니다. 제대로 작동합니다. 예를 들어, 나를위한 Steam은 64 비트입니다. "실제"키가 HKLM \ SOFTWARE \ WOW6432Node \ Valve.이기 때문에 / reg : 32를 추가하지 않으면 HKLM \ SOFTWARE \ Valve \ Steam \ InstallPath 쿼리가 실패합니다.
— Kadser

수정 : 증기는 32 비트, 내 OS는 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 key = SOFTWARE \ rgagnon.com \ aa. WinRegistry.createKey (WinRegistry.java:157). 그것을 해결하는 방법.
— Kyaw Zin Htun

마지막으로 중요한 참고 사항을 읽으십시오. 레지스트리 목적 작성 방법을 수정하지 않았으므로 수신 된 것과 같습니다.
— pratapvaibhav19

2
이 솔루션에서 매우주의하십시오. 허용 ​​된 답변과 같지 않습니다. 맨 아래 레벨에서는 Preference 클래스에 대한 호출을 "reg query"명령에 대한 쉘로 대체하지만,이를 즉시 인식하지 못할 수있는 승인 된 응답처럼 보입니다.
— Bill K

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는 레지스트리를 사용하여 기본 설정을 저장하지만 전체 레지스트리에 액세스하는 데 사용할 수는 없습니다.

그러나 David Croft라는 해적은 JNI없이 Java에서 Windows 레지스트리 를 읽는 데 Sun의 기본 설정 API 구현에서 메소드를 사용할 수 있다는 것을 알아 냈습니다 . 그것에 약간의 위험이 있지만, 볼만한 가치가 있습니다.



4

Preferences API 접근법은 레지스트리의 모든 브랜치에 대한 액세스를 제공하지 않습니다. 실제로, 환경 설정 API가 환경 설정을 저장하는 위치에만 액세스 할 수 있습니다. .NET과 같은 일반적인 레지스트리 처리 API가 아닙니다.

Mark가 알 수 있듯이 모든 키를 읽거나 쓰려면 JNI 또는 외부 도구가 접근해야한다고 생각합니다.


Preferences API가 실제로 Java 자체의 환경 설정 방법이 싫습니다. 당신이 말한 것처럼 더 일반적이기를 바랍니다.

3

WinRun4J 시도 할 수 있습니다. 이것은 Windows Java 실행기 및 서비스 호스트이지만 레지스트리 액세스를위한 라이브러리도 제공합니다.

(btw 나는이 프로젝트에서 일하고 있으므로 질문이 있으면 알려주십시오)


3

@David의 답변에 대한 나의 이전 편집은 거부되었습니다. 여기에 대한 유용한 정보가 있습니다.

이 "마술"은 Sun Preferences이 JDK의 일부로 Windows 용 클래스를 구현하기 때문에 작동 하지만 개인용 패키지 입니다. 구현의 일부는 JNI를 사용합니다.

구현은 팩토리 메소드를 사용하여 런타임에 선택됩니다. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/prefs/Preferences.java# 환경 설정.

실제 질문 : 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를 많이 호출합니다.
— Daniel

0

이것은 꽤 오래되었지만 Windows 플랫폼에서 사용하는 더 나은 유틸리티는 다음과 regini같습니다.

처리하기위한 단일 호출 :

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

모든 마술을 할 것입니다. javaw.exe 인수를 추가하기 위해 레지스트리에서 변경 해야하는 servany.exe를 사용하여 jar를 Windows 서비스로 만들면서 시도했지만 완벽하게 작동합니다. http://support.microsoft.com/kb/264584 에서 읽을 수 있습니다 .


0

이것은 미쳤다 ... 나는 여기의 게시물 중 하나에서 코드를 가져 와서 18 개의 주석이 더 있다는 것을 보지 못했습니다.

어쨌든, 나는 그 코드의 지옥을 if와 메소드가 적은 것으로 리팩토링했습니다 ...

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

이것은 David의 답변 에서와 동일한 Java 내부 API를 사용 하지만 완전히 다시 작성했습니다. 지금은 더 짧고 사용하기 좋습니다. 또한 HKEY_CLASSES_ROOT 및 기타 두드러기에 대한 지원을 추가했습니다. 기본 API로 인해이 접근 방식으로는 피할 수없는 다른 제한 사항 (DWORD 지원 없음 및 유니 코드 지원 없음)이 여전히 있습니다. 여전히 기본 문자열 읽기 / 쓰기 만 필요하고 기본 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

David의 답변에 대한 응답으로 몇 가지 개선 사항을 수행합니다.

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

Java 코드를 사용하여 이러한 "REG QUERY"명령을 실행할 수 있습니다 .

이것을 명령 프롬프트에서 실행하고 Java 코드에서 명령을 실행하십시오.

HKEY_LOCAL_MACHINE "소프트웨어 \ Microsoft \ Windows NT \ CurrentVersion"

제품 이름 버전 등과 같은 세부 정보를 검색하려면 / v amd "name"을 사용하십시오.

HKEY_LOCAL_MACHINE "소프트웨어 \ Microsoft \ Windows NT \ CurrentVersion"/ v "제품 이름"


URL을 참조하십시오 : - stackoverflow.com/questions/7112259/...는 이 코드에서 "REG QUERY"를 실행하려고합니다.
— Palak Nagar

-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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.