2016-09-15 131 views
0
不工作

我的筆記本電腦配置爲64位窗口8.註冊表鍵創建在java中

當用戶選擇PDF文件並執行,當時我需要添加上下文菜單中右鍵單擊。

我googling太多,我找到了一些解決方案。但沒有人能解決我的問題。

我發現下面的鏈接,我的問題

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

另一溶液I使用兩個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); 

在這種情況下,註冊表項不創建。

兩種情況都可以完全讀取值,但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. 

請幫助我。任何其他解決方案如何創建註冊表項?

+0

你似乎在混合HKEY_CURRENT_USER和HKEY_CLASSES_ROOT,你可能需要後者不是前者 –

+0

Advapi32Util。registryDeleteKey不會創建密鑰,它會嘗試**刪除**一個密鑰 –

+0

從'key'中刪除''HKEY_CLASSES_ROOT「+ File.separator',然後嘗試'WinRegistry.createKey(WinRegistry.HKEY_CLASSES_ROOT,key);' –

回答

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

的主要問題是錯鍵目錄。 但現在我得到了正確的密鑰目錄..