3

USB ストレージ デバイスがプログラムによって自動検出される機能を実装しようとしています。

をリッスンする必要があることを理解しておりWM_DEVICECHANGE、 を使用しましたQAbstractNativeEventFilterが、これは SD カードがリーダーに挿入または取り外されているという特定のケースをキャッチしません (または、私の特定のケースでは、「大容量ストレージをオンにする」ボタンを押します)自分の携帯電話に)。

いくつかのグーグルで、私はこの投稿を見つけました: Windowsメッセージを使用して、ドライブへのメディアの挿入を検出しますSHCNE_MEDIAINSERTEDSHCNE_MEDIAREMOVED

私の問題は、リンカが を見つけられないように見えることSHChangeNotifyRegisterです。Qt Creator の内部で のコード補完宣言をslobj.h取得していますが、コンパイルすると次のようになります。

error: undefined reference to `_imp__SHChangeNotifyRegister@24'

その後ld、終了コード 1 で失敗します。

リンカーが見つけられないものについて途方に暮れています。インクルードは QtCreator 内で問題ありませんshell32.dll。実行していますmingw4.8 32bitが、これは別のコンパイラでコンパイルされた dll を使用できない場合ですか? また、.pro ファイルに追加しようwin32: LIBS += -lshell32としても無駄でした。またlib、Windows 7 SDK のフォルダーをパス変数に追加しました。

私のコードは次のとおりです (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 の提案に従って、いくつかのことを理解しました。

  • MSVC 用だと思うので、Windows SDK の shell32.lib は使用していません。
  • 独自の shell32.a に対する mingw リンク

  • objdump -x shell32.a私のmingwディストリビューションから使用したところ、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 にリンクするか、Windows ビルドに MSVC を使用するかのいずれかを検討する必要があると思います。

したがって、私の質問に対する答えは次のとおりだと思います:

答え:

mingw が特定の msvc .lib ファイルを使用できることがわかりました。今回は、Windows SDK バージョンの shell32.lib に適切にリンクし、すべてが機能しているようです。要するに、これを私の.proファイルに追加する必要がありました:

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

2 に答える 2

0

アプリをコンパイルしようとしているときに、同様のエラーが発生しました。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)"

結局、問題は単純でした。32 ビット ツールキットではなく、x64 MSVC ツールキットを使用してビルドしていたのです。

理由はわかりません。私は 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
于 2014-09-27T00:06:42.093 に答える