1

サードパーティのアプリケーションと通信する必要があります。そのための唯一の方法は、提供されているCOMコンポーネントにアクセスすることです。インタラクションには約3分かかるため、バックグラウンドで行う必要があります。だから私がやろうとしたのは、オプション「embeddinterop-types」=trueのコンポーネントへの参照を追加し、インターフェイスを介して非常に基本的なデータを読み取るテストを作成することです。これを行うための文書化された方法は、次のコードによるものです。

System sys = new System();
if(Convert.ToBoolean(sys.Initialize()) && Convert.ToBoolean(sys.Login("John Smith", out userInstance)))
Project proj = new Project();
if (Convert.ToBoolean(proj.Open(sys, m_projName, m_scenarioName)))
    someValue = proj.Name;

これは、BackgroundWorkerが使用されるまで完全に機能します。次に、コードの最初の行に次のエラーが表示されます。

タイプ'System.__ComObject'のCOMオブジェクトをインターフェイスタイプ'ICAPILib.System'にキャストできません。次のエラーが原因で、IID'{1F5EB3E2-35F6-11D2-A191-0060083A260B}'のインターフェイスのCOMコンポーネントに対するQueryInterface呼び出しが失敗したため、この操作は失敗しました。タイプライブラリ/DLLの読み込み中にエラーが発生しました。(HRESULTからの例外:0x80029C4A(TYPE_E_CANTLOADLIBRARY))。

コンポーネントの再登録を試しましたが、成功しませんでした。

BackgroundWorkerを使用する場合、スレッドアパートメントタイプは明らかにMTAです。COMコンポーネントでは、ThreadingModelがapartmentに設定されています。この記事 http://msdn.microsoft.com/en-us/library/eaw10et3.aspx を正しく理解していれば、相互運用機能のマーシャリングでオブジェクトへのアクセスを処理する必要があります。

誰かが私がこの仕事をするために何を試みることができるかについての手がかりを持っていますか?

4

2 に答える 2

1

何が起こったかというと、COM マーシャラーがオブジェクトをマーシャリングできませんでした。

最初の答え:標準マーシャリングにはタイプ ライブラリが必要です。オブジェクトのタイプ ライブラリが正しく登録されていないため、エラーが発生した可能性があります。x86 または x64 を使用していますか? ライブラリを REGTLB に登録してみてください。

2 番目の答え:それがうまくいかない場合、簡単な答えは STA アパートメント タイプのスレッドを使用することです。これは、BackgroundWorker を使用できないことを意味する場合がありますが、完了時に破棄する特別に作成されたスレッドを使用する必要がある場合があります。3 分間の操作について話している場合、追加のオーバーヘッドは無視できます。

マーシャリングを避けるために、オブジェクトは使用元のスレッドで作成する必要があり、アパートメント タイプはオブジェクトのスレッド モデルと互換性がある必要があります。

于 2012-05-16T08:24:40.977 に答える