使用JNA检测AppData\LocalLow的位置

发布于 2024-11-06 09:24:44 字数 1613 浏览 5 评论 0原文

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

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

这里我们有 C# 中的解决方案

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

}

I'm trying to detect the location of AppData\LocalLow work on Java with JNA on Windows 7. But the closest function available for the job is:

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

Here we have the Solution in C#

But in my case, JAVA + JNA, I'm wondering how I can use the LocalLow GUID with SHGetFolderPath only, or maybe I should look at the problem from a different angle (maybe JNI would be better here?)

If somebody can help on that, thanks

Cheers

EDIT:
Ok, now I added SHGetKnownFolderPath, but here, it keeps returning me strings like that "?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);
   }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

纵情客 2024-11-13 09:24:44

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

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

You can extend Shell32 (or create your own similar class) to get access to the SHGetKnownFolderPath API:

W32API.HRESULT SHGetKnownFolderPath(
                          Guid.GUID rfid, 
                          W32API.DWORD dwFlags, 
                          W32API.HANDLE hToken, 
                          char[] pszPath);
两人的回忆 2024-11-13 09:24:44

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

This Question is Somewhat old However I managed to Solve this issue.
allow me to explain why Kyro approach does not work quite well. This is due
SHGetKnownFolderPath uses a POINTER and not a String or A character array (that why show odd output) . therefore you need to use something like this:

public int SHGetKnownFolderPath(Guid.GUID rfid, int dwFlags, HANDLE hToken, PointerByReference pszPath);
a pointer by reference...

so on this case i attach a example I used:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文