我正在尝试实现一项功能,即我的程序会自动检测USB存储设备。
我知道我需要收听WM_DEVICECHANGE
,并且已经使用了QAbstractNativeEventFilter
,但这并没有抓住特定的案例,即从读卡器中插入或移除的SD卡(或在我的特定情况下按下手机上的“打开大容量存储空间”按钮。
通过一些谷歌搜索,我发现了这篇帖子:Detect insertion of media into a drive using windows messages,它准确描述了我需要使用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文件中无效,并且还将Windows 7 SDK的lib
文件夹添加到我的路径变量中。
我的代码如下(注意我对winapi 100%没用,所以这个代码可能会因为我正在修补它而大量破坏):
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
);
评论也欢迎这可能有助于我更好地阐述这个问题。
更新
根据Carey和Michaels在笔记中的建议我已经找到了一些东西:
mingw链接自己的shell32.a
使用了我的mingw发行版中的objdump -x shell32.a
,我找不到对SHChangeNotifyRegister的引用。
在Windows SDK的objdump -x shell32.lib
上使用shell32.lib
我可以找到该行:
[ 3](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__SHChangeNotifyRegister@24
这让我相信与mingw 4.8一起发布的shell32.a是不完整的,因此我的程序不会链接。
所以我想我将探索更新版本的mingw 如果存在或者使用mingw链接WindowsSDK,我认为这是不可能的或使用MSVC进行我的Windows版本。
因此,我认为我的问题的答案是:“它没有链接,因为你的shell32.a不包含.h中的所有内容”?
解答:
原来mingw可以使用某些msvc .lib文件。所以这一次我正确地链接到了Windows SDK版本的shell32.lib,一切似乎都有效。简而言之,这需要添加到我的.pro
文件中:
win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
答案 0 :(得分:2)
所以我可以接受这个问题的答案,我会在这里发布解决方案。
阅读凯里和迈克尔对这个问题的评论给了我一个关于错误的线索。
听起来你要么因为某种原因没有链接到Shell32.lib,要么你的Shell32.lib没有导出_SHChangeNotifyRegister @ 24函数。尝试查找Shell32.lib文件,在命令提示符下键入“dumpbin / exports shell32.lib”,查看_SHChangeNotifyRegister @ 24函数是否已导出
基本上,mingw链接的shell32.a
缺少SHChangeNotifyRegister
的定义(shlobj.h
的mingw版本有此声明) - 你可以阅读我是如何得出这个结论的更新问题。
要修复该解决方案,我使用了我已经存在的Windows SDK中的shell32.lib
副本 - 我认为可以找到here。幸运的是,mingw可以链接.lib文件。
要将新的shell32.lib
与我的QT Qbuild .pro
文件相关联,我使用了以下内容:
win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32
答案 1 :(得分:0)
我在尝试编译应用时遇到了类似的错误。我希望使用MSVC 2013工具包构建Qt Creator。我的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 ++开发人员,但看起来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