2013-08-04 70 views
3

我试图实现一个功能,由我的程序自动检测USB存储设备。SHChangeNotifyRegister与QT/MinGW 4.8不能链接

我明白,我需要监听WM_DEVICECHANGE,并使用QAbstractNativeEventFilter做了,但这不赶这是被插入或从读卡器取出SD卡的特定情况下(或在我的特定情况下,力推“打开海量存储“按钮在我的手机上)。

一些谷歌搜索,我发现这个职位:Detect insertion of media into a drive using windows messages其中描述了我需要使用SHCNE_MEDIAINSERTEDSHCNE_MEDIAREMOVED

我的问题是我的链接器似乎无法找到SHChangeNotifyRegister。里面Qt Creator中的我得到的代码完成的声明slobj.h,但在编译我得到这个:

error: undefined reference to `[email protected]' 

然后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 
); 

评论也欢迎可能会帮助我更好地制定这个问题。

UPDATE:

继笔记我已经想通了一些事情Carey和迈克尔斯建议:

  • 我不使用SHELL32.LIB从Windows SDK,因为我觉得这是针对MSVC的。
  • 对自己的shell32.a

  • MinGW的链接已经使用objdump -x shell32.a从我MinGW的分布,我可以找到没有提及SHChangeNotifyRegister。

  • shell32.lib从窗户使用objdump -x shell32.lib SDK我可以找到行:

    [ 3](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 [email protected] 
    

这使我相信,随着MinGW的4.8发布的shell32.a是不完整的,因此我的方案将不链接。

所以我觉得如果一个存在,或与MinGW的,我认为这是不可能的,或者使用MSVC我的窗口建立链接对WindowsSDK我将探索MinGW的任何一个较新的版本。

因此,我认为我的问题的答案是:“它不链接,因为你的shell32.a不包含.h中的所有内容”?

答:

原来的MinGW可以使用一定的MSVC .lib文件。所以这次我正确地链接到shell32.lib的Windows SDK版本,并且一切似乎都起作用。总之这需要添加到我的.pro文件:

win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32 
+0

这样的连锁故障通常意味着你有一个函数参数,返回类型或调用约定错误。 –

+1

这听起来不是因为某种原因而不与Shell32.lib链接,或者您的Shell32.lib不会导出_SHChangeNotifyRegister @ 24函数。尝试找到Shell32.lib文件,在命令提示符处键入“dumpbin/exports shell32.lib”,并查看是否导出_SHChangeNotifyRegister @ 24函数 –

+0

好吧,我认为这些回复让我更接近理解正在发生的事情。我要更新这个问题,也许你们中的一个可以把你的信息作为答案,因为我认为我会接受一个。如果我得到了棒的错误结束,那么请在消息中说明:) – Kasheen

回答

2

所以,我可以接受这个问题,我会在这里张贴的解决答案。

凯瑞和迈克尔对这个问题的评论让我知道什么是错的线索。

这听起来不是因为某种原因与Shell32.lib链接,或者说你的Shell32.lib没有导出_SHChangeNotifyRegister @ 24函数。尝试找到SHELL32.LIB文件,键入“DUMPBIN /出口SHELL32.LIB”在命令提示符下,如果_SHChangeNotifyRegister @ 24函数出口

看基本上是MinGW的被链接对shell32.a缺乏的定义SHChangeNotifyRegistershlobj.h的铭文版本有此声明) - 您可以阅读我在问题更新中如何得出结论。

要修复解决方案,我使用了一个Windows SDK中的shell32.lib副本,我已经放置 - 我认为这可以找到here。幸运的是,mingw可以链接.lib文件。

要与我的QT Qbuild .pro文件链接的新shell32.lib我用下面的:

win32: LIBS += -L"C:/Path/To/Microsoft/Microsoft SDKs/Windows/v7.1/Lib/" -lshell32 
0

我得到一个类似的错误,而试图编译的应用程序。我想要使​​用MSVC 2013工具包构建Qt Creator。我在.pro文件有LIBS += -ladvapi32,但仍然得到:

FilePathUtilities.obj : error LNK2019: 
unresolved external symbol __imp_ShellExecuteExW 
referenced in function "void __cdecl FileShowInExplorer(class CStr const &,int)" 

的问题最终是简单的:我是用64 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 
        [email protected] 
        [email protected] 
        [email protected] 
        [email protected] 
        [email protected] 
        [email protected] 


/* 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