我是Java jna API的新手,并且Win32 API方法有问题。我需要从Win32 API获取IShellFolder对象,因为我需要文件的IContextMenu对象。但是,当我从jna ParseDisplayName调用Win32 API方法时,我得到了相同的结果错误:
“该系统找不到指定的文件”。我在下面附加了我的代码。
String directory = "c:\\Users";
IntByReference pchEaten = new IntByReference();
pchEaten.setValue(0);
PointerByReference ppidl = new PointerByReference();
IntByReference pdwAttributes = new IntByReference();
pdwAttributes.setValue(0);
PointerByReference desktopFolder = new PointerByReference();
WinNT.HRESULT hResult = Shell32.INSTANCE.SHGetDesktopFolder(desktopFolder);
IShellFolder shellFolder = IShellFolder.Converter.PointerToIShellFolder(desktopFolder);
if (COMUtils.SUCCEEDED(hResult) && shellFolder != null) {
hResult = shellFolder.ParseDisplayName(new WinDef.HWND(Pointer.NULL), Pointer.NULL, directory, pchEaten, ppidl, pdwAttributes);
if (COMUtils.SUCCEEDED(hResult)) {
return true;
}
else {
return false;
}
}
else {
return false;
}
我测试过的每个目录都有相同的错误。
非常感谢你。
最佳答案
欢迎使用StackOverflow!
正如我在评论中提到的,iShellFolder::ParseDisplayName
的documentation表示第三个参数pszDisplayName
是“以显示名称结尾的以空值结尾的Unicode字符串”。在Windows文档中遇到“ Unicode”时,将强制使用“ UTF-16”字符集。
JNA中Windows Unicode字符串的正确映射是WString
。不幸的是,JNA将此参数映射为String
,它是单字节UTF-8编码(即使Java在内部将字符串存储在UTF-16中)。
您可以通过创建更长的String
来解决此问题,该String
将UTF-8转换为UTF-16(小字节序)编码(以字节为单位)。之前,我曾发布过一个ASCII解决方案,该方案利用了已知的编码,但是更好的解决方案是使用String的方法将字节提取为UTF-16LE,然后从这些字节中创建一个'\u0000'
对象。此代码进行转换:
String test = "müller_test.pdf";
byte[] utf16 = test.getBytes("UTF-16LE");
System.out.println("utf16 that we need to pass:\n" + Arrays.toString(utf16));
String wString = new String(utf16);
System.out.println("Pass this to Windows:\n" + wString);
产生以下输出:
utf16 (little endian) that we need to pass:
[99, 0, 58, 0, 92, 0, 85, 0, 115, 0, 101, 0, 114, 0, 115, 0]
Pass this to Windows:
m � l l e r _ t e s t . p d f
不幸的是,通过检查字节,我不确定它是否包含空终止符,因此您可能希望在执行此操作之前将
wstring
字符添加到字符串的末尾。因此,最终您将获得以下内容:
String wstring = new String((test + '\u0000').getBytes("UTF-16LE"));
将传递到需要Unicode字符串的Windows,您已全部完成。
关于java - 使用jna获取IShellFolder,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57460980/