Определите местоположение AppData\LocalLow с помощью JNA

Я пытаюсь определить местонахождение AppData\LocalLow работы на Java с помощью JNA в Windows 7. Но ближайшая функция, доступная для работы:

W32API.HRESULT SHGetFolderPath(W32API.HWND hwndOwner,int nFolder,W32API.HANDLE
                               hToken,W32API.DWORD dwFlags,char[] pszPath)

Здесь у нас есть решение на C#

Но в моем случае, JAVA + JNA, мне интересно, как я могу использовать LocalLow GUID только с SHGetFolderPath, или, может быть, я должен посмотреть на проблему под другим углом (может быть, здесь JNI будет лучше?)

Если кто-то может помочь в этом, спасибо

Ваше здоровье

РЕДАКТИРОВАТЬ: Хорошо, теперь я добавил SHGetKnownFolderPath, но здесь он продолжает возвращать мне такие строки, как "?f"

static interface Shell32 extends Library {

    public static final int     MAX_PATH            = 260;
    public static final String  FOLDERID_APPDATALOW = "{A520A1A4-1780-4FF6-BD18-167343C5AF16}";

    static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32",
                    Shell32.class, OPTIONS);

    public int SHGetKnownFolderPath(Guid.GUID rfid, int dwFlags, HANDLE hToken,
                    char[] pszPath);
}

public static void main(String[] args) {

   char[] pszPath = new char[Shell32.MAX_PATH];
   Guid.GUID localLowId = Ole32Util.getGUIDFromString(Shell32.FOLDERID_APPDATALOW);
   int hResult = Shell32.INSTANCE.SHGetKnownFolderPath(localLowId, 0, null, pszPath);

   if (hResult == 0) {
       String path = new String(pszPath);
       int len = path.indexOf('\0');
       path = path.substring(0, len);
       System.out.println(path);
   } else {
       System.err.println("Error: " + hResult);
   }

}


person Kyro    schedule 10.05.2011    source источник
comment
Вероятно, вам нужно расширить StdCallLibrary, а не библиотеку, поскольку API w32 использует соглашение о вызовах stdcall.   -  person technomage    schedule 08.07.2011


Ответы (2)


Вы можете расширить Shell32 (или создать свой собственный аналогичный класс), чтобы получить доступ к SHGetKnownFolderPath API:

W32API.HRESULT SHGetKnownFolderPath(
                          Guid.GUID rfid, 
                          W32API.DWORD dwFlags, 
                          W32API.HANDLE hToken, 
                          char[] pszPath);
person Michael Brewer-Davis    schedule 10.05.2011

Этот вопрос несколько устарел, однако мне удалось решить эту проблему. позвольте мне объяснить, почему подход Kyro не работает достаточно хорошо. Это связано с
SHGetKnownFolderPath использует POINTER, а не массив символов String или A (поэтому отображается нечетный вывод). поэтому вам нужно использовать что-то вроде этого:

public int SHGetKnownFolderPath(Guid.GUID rfid, int dwFlags, HANDLE hToken, PointerByReference pszPath); указатель по ссылке...

поэтому в этом случае я прикрепляю пример, который я использовал:

static interface Shell32 extends StdCallLibrary {
    public static final String  FOLDERID_APPDATALOW = "{A520A1A4-1780-4FF6-BD18-167343C5AF16}";

    static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32",
                    Shell32.class, W32APIOptions.UNICODE_OPTIONS);

    public int SHGetKnownFolderPath(Guid.GUID rfid, int dwFlags, HANDLE hToken,
                    PointerByReference pszPath);
}

public static void main(String[] args) {
   Guid.GUID localLowId = Ole32Util.getGUIDFromString(Shell32.FOLDERID_APPDATALOW);
   PointerByReference e= new PointerByReference();
   int hResult = Shell32.INSTANCE.SHGetKnownFolderPath(localLowId, 0, null, e);

   if (hResult == 0) {
       char delim='\0';
       char Array[]=e.getValue().getCharArray(0,255);
       for (int i = 0; i < Array.length; i++) {
         if(Array[i]==delim){
             char temparr[]=new char[i];
             System.arraycopy(Array,0,temparr,0,i);
             Array=temparr;
             break;
         }  
       }
       /*dont forget to release the Pointer*/
       Ole32.INSTANCE.CoTaskMemFree(e.getValue());
       System.out.println(Array);
   } else {
       System.err.println("Error: " + hResult);
   }

}
private static interface Ole32 extends StdCallLibrary {

    Ole32 INSTANCE = (Ole32) Native.loadLibrary(
            "Ole32", Ole32.class, W32APIOptions.UNICODE_OPTIONS);

    void CoTaskMemFree(Pointer pv);
}
person Sith Nazgûl Cat    schedule 22.08.2012
comment
Спасибо за ваш ответ, но в итоге я использовал Cache.getCacheDir() из deploy.jar: javasourcecode.org/html/open-source/jdk/jdk-6u23/com/sun/deploy/ (в основном мне нужен был доступ к LocalLow для получения папка с кешем...) - person Kyro; 28.08.2012