Window Registry创建的密钥在java中不起作用

时间:2016-09-15 10:21:13

标签: java windows windows-8 registry

我的笔记本电脑配置是64位窗口8。

当用户选择pdf文件并在那时右键单击时,我需要添加上下文菜单。

我在谷歌搜索过多,我发现了一些解决方案。但没人能解决我的问题。

我在下面找到了我的问题链接

read/write to Windows Registry using Java

How can I add a context menu to the Windows Explorer for a Java application?

案例1: 我试过WinRegistry类

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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
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 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
       * @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;
      }
}

当我得到typeId时,对于哪个软件使用pdf视图,我得到了适当的价值 我的代码在下面

String string = WinRegistry.readString(WinRegistry.HKEY_CURRENT_USER, "Software"+File.separator+"Microsoft"+File.separator+"Windows"+File.separator+"CurrentVersion"+File.separator+"Explorer"+File.separator+"FileExts"+File.separator+".pdf"+File.separator+"UserChoice", "ProgId");
        System.out.println(string);

我得到FoxitReader.Document是一个完美的价值。

但是当我通过下面的代码

创建注册表项时
String key = "HKEY_CLASSES_ROOT"+File.separator+string+File.separator+"shell"+File.separator+"PDF View";
        WinRegistry.createKey(WinRegistry.HKEY_CURRENT_USER, key);

但我失败了。这个关键不是创造。

案例2: 我找到了另一种使用jna的解决方案

我使用两个jar文件jna-4.2.2jna-platform-4.2.2

获取pdf视图的软件,我写下代码

String string = Advapi32Util.registryGetStringValue(
        WinReg.HKEY_CURRENT_USER, "Software"+File.separator+"Microsoft"+File.separator+"Windows"+File.separator+"CurrentVersion"+File.separator+"Explorer"+File.separator+"FileExts"+File.separator+".pdf"+File.separator+"UserChoice", "ProgId");
System.out.println(string);

我的价值与以前的价值相同。

但是当我创建注册表项

String key = "Computer"+File.separator+"HKEY_CLASSES_ROOT"+File.separator+string+File.separator+"shell"+File.separator+"PDF View";
    Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, key);

在这种情况下,不会创建注册表项。

这两种情况都完美地获得了readValue,但是createKey没有工作。

这两种情况我收到了以下警告信息:

Sep 15, 2016 3:40:56 PM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

请帮帮我。有关如何创建注册表项的任何其他解决方案吗?

1 个答案:

答案 0 :(得分:1)

我通过写这样的

解决了我的问题
String string = WinRegistry.readString(WinRegistry.HKEY_CURRENT_USER, "Software"+File.separator+"Microsoft"+File.separator+"Windows"+File.separator+"CurrentVersion"+File.separator+"Explorer"+File.separator+"FileExts"+File.separator+".pdf"+File.separator+"UserChoice", "ProgId");
      String key = "Software"+File.separator+"Classes"+File.separator+string+File.separator+"shell"+File.separator+"PDF View";
    WinRegistry.createKey(WinRegistry.HKEY_CURRENT_USER, key);

主要问题是错误的密钥目录。 但现在我得到了正确的密钥目录..