SHChangeNotifyRegister с QT / MinGW 4.8 не удается связать
Я пытаюсь реализовать функцию, при которой запоминающие устройства USB автоматически определяются моей программой.
Я понимаю, что мне нужно слушать WM_DEVICECHANGE
, и сделал это с помощью QAbstractNativeEventFilter
, но это не ловит конкретный случай, который является SD-карта вставляется или удаляется из считывателя (или в моем конкретном случае, нажав кнопку "Включить mass storage" на моем телефоне).
После некоторого гугления я нашел этот пост: обнаружение вставки носителей в диск с помощью сообщений windows который точно описывает, что мне нужно, который использует SHCNE_MEDIAINSERTED
и SHCNE_MEDIAREMOVED
.
Моя проблема заключается в том, что мой компоновщик не может найти SHChangeNotifyRegister
. Внутри Qt Creator я получаю объявления завершения кода для slobj.h
, но при компиляции я получаю следующее:
error: undefined reference to `_imp__SHChangeNotifyRegister@24'
Затем ld
завершается ошибкой с кодом выхода 1.
Я в недоумении относительно того, что компоновщик не может найти, включенные прекрасно внутри QtCreator-так что он не может найти shell32.dll
? Я бегу mingw4.8 32bit
это случай, когда он не может использовать библиотеку dll, скомпилированную с другим компилятором? Я также попытался добавить win32: LIBS += -lshell32
в свой файл. pro безрезультатно, а также добавил папку lib
SDK для windows 7 в переменную path.
Мой код выглядит следующим образом (обратите внимание, что я на 100% бесполезен с winapi, так что этот код, вероятно, массово сломан, поскольку я был в середине работы с ним):
MainWindow w(deviceMgr);
w.show();
int sources = 0x0001 | 0x0002 | 0x8000; // Interupt, Shell, New Delivery Missing Defs
LONG events = SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED;
PIDLIST_ABSOLUTE pidl;
SHGetFolderLocation((HWND) w.winId(), CSIDL_DRIVES, NULL, 0, &pidl);
SHChangeNotifyEntry entries[] = { pidl, false };
ULONG code = SHChangeNotifyRegister(
(HWND) w.winId(),
sources,
events,
WM_APP + 1,
ARRAYSIZE(entries),
entries
);
Приветствуются также комментарии, которые могли бы помочь мне лучше сформулировать этот вопрос.
Обновление:
Вслед За Кэри и предложения Майклса в заметках я выяснил несколько вещей:
- я не использую shell32.lib из Windows SDK, потому что я думаю, что это для MSVC.
-
Mingw связывает против своего собственного shell32.a
-
Используя
objdump -x shell32.a
из моего распределения mingw, я не могу найти ссылку на SHChangeNotifyRegister. -
Используя
objdump -x shell32.lib
наshell32.lib
из Windows SDK я могу найти строку:[ 3](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__SHChangeNotifyRegister@24
Это заставляет меня поверьте, что шелл32.дистрибутив с mingw 4.8 является неполным и поэтому моя программа не будет связываться.
Поэтому я думаю, что изучу либо более свежую версию mingw , если она существует, либо связывание с WindowsSDK с mingw, что, по моему мнению, невозможно, либо использование MSVC для моих сборок windows.
Поэтому я думаю, что ответ на мой вопрос таков: "это не связано, потому что ваш shell32.a не содержит всего, что находится в .ч"?Ответ:
Оказывается, mingw может использовать определенный msvc .файлы lib. Так что на этот раз я правильно подключился к версии SHELL32 для Windows SDK.Либ и все, кажется, работает. Короче говоря, это нужно было добавить в мой файл .pro
:
win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
2 ответа:
Чтобы я мог принять ответ на этот вопрос, я опубликую решение здесь.
Чтение комментариев Кэри и Майкла по этому вопросу дало мне ключ к разгадке того, что было неправильно.Похоже, что либо вы не связываетесь с Shell32.Либ по какой-то причине или что ваш Shell32.lib не экспортирует функцию _SHChangeNotifyRegister@24. Попробуйте найти Shell32.lib файл, тип " dumpbin / exports shell32.lib " в командной строке и посмотрите, если _SHChangeNotifyRegister@24 функция экспортируется
По существу
shell32.a
, что mingw связывал против отсутствовало определениеSHChangeNotifyRegister
(версия mingwshlobj.h
имела это объявление) - вы можете прочитать, как я пришел к этому выводу в обновлениях вопроса.Для исправления решения я использовал копию
shell32.lib
из пакета SDK для Windows, который у меня лежал - я думаю, что это можно найти здесь. К счастью, мингв мог связать это .файл lib.Чтобы связать новый
shell32.lib
с моим Qt Qbuild.pro
файлом I используется следующее:win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
Я получал аналогичную ошибку при попытке скомпилировать приложение. Я хотел построить Qt Creator с помощью инструментария MSVC 2013. У меня было
LIBS += -ladvapi32
в моем файле.pro
, но я все еще получал:FilePathUtilities.obj : error LNK2019: unresolved external symbol __imp_ShellExecuteExW referenced in function "void __cdecl FileShowInExplorer(class CStr const &,int)"
Проблема оказалась простой: я строил с помощью инструментария x64 MSVC вместо 32-битного инструментария!
Не знаю почему, я не c++ dev, но похоже, что 32-и 64-битные идентификаторы не идентичны:
/* 32 BIT LIBRARY */ /c/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib $ "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe" -exports shell32.lib | grep ShellEx _WOWShellExecute@28 _ShellExecuteW@24 _ShellExecuteExW@4 _ShellExecuteExA@4 _ShellExecuteEx@4 _ShellExecuteA@24 /* 64 BIT LIBRARY */ /c/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib/x64 $ "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\dumpbin.exe" -exports shell32.lib | grep ShellEx ShellExecuteA ShellExecuteEx ShellExecuteExA ShellExecuteExW ShellExecuteW WOWShellExecute