マルチスレッド アパートメントからシェル関数とインターフェイスを呼び出す

マルチスレッド アパートメントとして初期化されたスレッドからシェル関数またはシェル インターフェイスを呼び出すか、シェル インターフェイスにアクセスすると、関数またはインターフェイスの機能が損なわれたり、完全に失敗したりする可能性があります。

元のバージョン: Windows シェルとインターフェイス
元の KB 番号: 287087

原因

CoInitializeEx (COINIT_MULTITHREADED) 呼び出すと、呼び出し元スレッドで作成されたオブジェクトの呼び出しを任意のスレッドで実行できます。 マルチスレッド アパートメントからアパートメント スレッド モデルを使用するオブジェクトにアクセスすると、COM はオブジェクトへのアクセスを同期します。 この同期を行うには、COM が オブジェクトへの呼び出しをマーシャリングする必要があります。 シェルは現在、オブジェクトをマーシャリングするために、タイプ ライブラリまたはプロキシ/スタブ コードを介して必要な情報を提供しないため、マルチスレッド アパートメントからシェル オブジェクトにアクセスしようとすると失敗します。

シェル関数に影響を与える可能性がある呼び出し

の呼び出しがシェル オブジェクトに CoInitializeEx (COINIT_MULTITHREADED) 依存する関数に与える影響の例を次に示します。

  • GetOpenFileName/GetSaveFileName

    ユーザーは、[開く] ダイアログ ボックスと [名前を付けて保存] ダイアログ ボックスを使用して、マイ ドキュメントなどの名前空間拡張フォルダーに移動できます。 ただし、ブラウザーで などの必要なインターフェイスを作成できないため、 IShellFolderこれらのフォルダーを 参照できません。

  • ShellExecute/ShellExecuteEx

    ShellExecuteフックを記述して、 のShellExecute機能を拡張したり、 インターフェイスをIShellExecuteHook実装したりできますShellExecuteExShellExecuteまたは ShellExecuteEx が呼び出されると、登録されたShellExecuteフックを読み込めません。

これらの両方の例では、、 などのシェル オブジェクトCoCreateInstanceIUnknown::QueryInterfaceへのインターフェイス ポインターを取得しようとしているコンポーネントは、通常、マルチスレッド アパートメントから呼び出されるとエラーE_NOINTERFACEで失敗します。 上で説明したように、要求されるオブジェクトの型情報やプロキシ/スタブ コードがないためです。

関連情報

プロセス、スレッド、およびアパートメント