【问题标题】:Detect the location of AppData\LocalLow with JNA使用 JNA 检测 AppData\LocalLow 的位置
【发布时间】:2011-05-10 16:18:31
【问题描述】:

我正在尝试在 Windows 7 上使用 JNA 检测 AppData\LocalLow 在 Java 上工作的位置。但最接近该工作的函数是:

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

这里有Solution in C#

但就我而言,JAVA + JNA,我想知道如何仅将LocalLow GUIDSHGetFolderPath 一起使用,或者我应该从不同的角度看待问题(也许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);
   }

}

【问题讨论】:

  • 您可能需要扩展 StdCallLibrary 而不是 Library,因为 w32 API 使用 stdcall 调用约定。

标签: java winapi java-native-interface jna ffi


【解决方案1】:

您可以扩展Shell32(或创建自己的类似类)以访问SHGetKnownFolderPath API:

W32API.HRESULT SHGetKnownFolderPath(
                          Guid.GUID rfid, 
                          W32API.DWORD dwFlags, 
                          W32API.HANDLE hToken, 
                          char[] pszPath);

【讨论】:

    【解决方案2】:

    这个问题有点老但是我设法解决了这个问题。 请允许我解释一下为什么 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);
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多