2013-08-04 71 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