Пользователи, сталкивающиеся с разработкой ПО для Windows, часто используют функцию AssocQueryString для определения ассоциаций файлов с определенными расширениями. Однако, при работе с изображениями, начиная с Windows 10, возникли некоторые недопонимания и проблемы.
Проблема
Функция AssocQueryString предназначена для получения информации об ассоциациях файлов, включая программы, открывающие файлы с определенными расширениями. Она успешно работает с документами, такими как PDF и TXT, но с изображениями (bmp, png, jpg, ico) результаты не возвращаются.
Контекст
В коде, приведенном в вопросе, используется функция AssocQueryString для попытки получения ассоциаций для расширения .bmp. Несмотря на то, что функция корректно работает с другими типами файлов, при использовании расширений изображений она возвращает пустую строку.
Подтвержденный ответ
Согласно комментариям, на вашей системе расширения изображений не ассоциируются с приложениями, а вместо этого используют DLL, вызываемые через Rundll32. Это подтверждается документацией ASSOCSTR:
ASSOCSTR_EXECUTABLE
Исполняемый файл из строки команды Shell verb. Если команда использует Rundll.exe, установите флаг ASSOCF_REMAPRUNDLL в параметре flags метода IQueryAssociations::GetString, чтобы получить целевой исполняемый файл.
И документацией ASSOCF:
ASSOCF_REMAPRUNDLL
Инструкция методам IQueryAssociations игнорировать Rundll.exe и возвращать информацию о его цели.
Альтернативный ответ
При вызове AssocQueryString, попробуйте установить параметр pszExtra в NULL, а не использовать конкретное действие. Также обратите внимание на последний параметр cchOut функции AssocQueryString:
cchOut [in, out]
Указатель на значение, которое при вызове функции должно быть установлено в количество символов в буфере pszOut. При успешном возврате функции, значение устанавливается в количество символов, фактически размещенных в буфере.
Вы устанавливаете переменную BufSize как размер в байтах буфера, а не в количестве символов. В более новых версиях Delphi, чем 2007, SizeOf(Char) равен 2. И всегда проверяйте возвращаемые значения на ошибки.
Пример кода
var
Buffer: string;
BufSize: DWord;
Res: HResult;
begin
BufSize := 0;
Res := AssocQueryString(
ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
ASSOCSTR_EXECUTABLE,
'.bmp',
nil,
nil,
@BufSize
);
if Res = S_FALSE then
begin
SetLength(Buffer, BufSize-1);
Res := AssocQueryString(
ASSOCF_REMAPRUNDLL or ASSOCF_NOTRUNCATE,
ASSOCSTR_EXECUTABLE,
'.bmp',
nil,
PChar(Buffer),
@BufSize
);
end;
If Res = S_OK then
ShowMessage(Buffer)
else
ShowMessage('Error ' + IntToStr(Res));
end;
Заключение
В Windows 10 ассоциации для изображений могут отличаться от Windows 7. В Windows 10 для открытия изображений используется DLL, а не исполняемый файл. Для получения информации об ассоциациях, используйте правильные параметры в функции AssocQueryString и обратите внимание на обработку возвращаемых значений.
Эта информация может быть полезна разработчикам, которые хотят проверить, есть ли у файла с определенным расширением ассоциированное приложение для просмотра, прежде чем загружать его в временную папку и открывать.
Разработчики ПО для Windows столкнулись с проблемой, что функция `AssocQueryString` перестала корректно работать с ассоциациями изображений в Windows 10, возвращая пустые строки вместо ожидаемых данных об ассоциациях.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.