JNA CoCreateInstance возвращает S_OK, но ShellLink/IShellLinkW завершается с ошибкой, указатель COM не равен нулю, но обJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 JNA CoCreateInstance возвращает S_OK, но ShellLink/IShellLinkW завершается с ошибкой, указатель COM не равен нулю, но об

Сообщение Anonymous »

Я создаю Java-приложение, которое сканирует папку «Последние файлы Windows» и преобразует ярлыки .lnk в их фактические пути к файлам. Я делаю это, используя JNA, JNA API и моделируя IShellLinkW и IPersistFile.
Каждый раз, когда я запускаю свой код, CoCreateInstance возвращает S_OK, а указатель COM не равен нулю, но мой объект ShellLink немедленно завершается с ошибкой, как и мой IPersistFile.load.
Это мой журнал отладки (я создал много отладочных сообщений) после очистки папки с последними файлами и скачиваем фиктивный PDF-файл:

Код: Выделить всё

Resolving: pdf-sample_0.pdf.lnk
===== ShellLink.createShellLink() BEGIN =====
CLSID_SHELL_LINK = {00021401-0000-0000-C000-000000000046}
IID_SHELL_LINK_W = {000214F9-0000-0000-C000-000000000046}
[1] Calling CoInitialize...
[1] CoInitialize HRESULT = 1  (S_FALSE)
[2] Calling CoCreateInstance...
[2] CoCreateInstance HRESULT = 0  (S_OK)
[2] HRESULT (hex) = 0x00000000
[2] Returned COM pointer (ppv) = native@0x1eeef60df60
!!! ShellLink create FAILED !!!
!!! HRESULT = 0x00000000
!!! ppv = native@0x1eeef60df60
Error resolving: pdf-sample_0.pdf.lnk
Мой вопрос: почему JNA считает этот указатель COM недействительным, когда CoCreateInstance возвращает S_OK? Использую ли я неправильные идентификаторы COM для классов/интерфейсов? Неправильные индексы виртуальных таблиц? Или что-то еще?
Соответствующий код
1. Соответствующие константы Config.java

Код: Выделить всё

public static final String WIN32_CLASS_ID_OBJECT_SHELL_LINK = "{00021401-0000-0000-C000-000000000046}";
public static final String WIN32_INTERFACE_ID_SHELL_LINK_WIDE = "{000214F9-0000-0000-C000-000000000046}";
public static final String WIN32_INTERFACE_ID_PERSIST_FILE = "{0000010B-0000-0000-C000-000000000046}";
public static final int WIN32_MAX_PATH = 260;
public static final int WIN32_VTABLE_GETPATH = 20;
public static final int WIN32_VTABLE_RESOLVE = 21;
public static final int WIN32_VTABLE_LOAD = 5;
2. Фрагмент ShellLink.createLink (похоже, здесь происходит основная проблема)

Код: Выделить всё

public static IShellLinkW createShellLink() {

// Initialize COM
WinNT.HRESULT initRes = Ole32.INSTANCE.CoInitialize(null);

// Create the ShellLink COM object
PointerByReference ppv = new PointerByReference();
WinNT.HRESULT hres = Ole32.INSTANCE.CoCreateInstance(
CLSID_SHELL_LINK,
null,
WTypes.CLSCTX_INPROC_SERVER,
IID_SHELL_LINK_W,
ppv
);

Pointer rawPtr = ppv.getValue();

// Failure
if (hres == null || hres.intValue() != WinNT.S_OK || rawPtr == null) {
Ole32.INSTANCE.CoUninitialize();
return null;
}

// Success
return new IShellLinkW(rawPtr);
}
Несмотря на то, что hres == S_OK и rawPtr != null, блок if все равно работает.
Я использую компьютер с Windows 10, а код работает на Java 17 с JNA 5.13.0. Папка, которую я сканирую, — %APPDATA%\Microsoft\Windows\Recent. Если это поможет, это приложение JavaFX.
Если это поможет, вот ссылка на репозиторий GitHub. Буду очень признателен за советы, спасибо!

Подробнее здесь: https://stackoverflow.com/questions/798 ... -pointer-i
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»