2012-01-11 10 views
3

C#のCOMクラスを使用すると問題が発生します。 COMクラスはC++ ATL 32ビットで開発されています。私はVBA、VB6、C++、JavaScriptからもMSTestを/ C#のからそれを使用する場合C#console-projectのCOMオブジェクトの使用

COMクラスが正常に動作します

奇妙な事があること、私はNUnitのテストから、またはからインスタンスを作成するときコンソールアプリケーションは例外を除いて失敗します:

System.InvalidCastException : Unable to cast COM object of type 'PvtsFlashLib.FlashClass' to interface type 'PvtsFlashLib.IFlash4'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{07065455-85CD-42C5-94FE-DDDC1B1A110F}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). 

誰かが正しい方向に向かうことができますか?

ご協力いただきありがとうございます。テスト・プロジェクトとコンソールプロジェクトのビルド設定に設定されて

:正常に動作しますMSTestを用

Copy Local = True 
Embed Interop Types = False 
Isolated = False 

コード:

Platform = x86 

両方のプロジェクトでCOM参照がに設定されています:

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using PvtsFlashLib; 

namespace TestProject1 
{ 
    [TestClass] 
    public class TestOfComMSTest 
    { 
     [TestMethod] 
     public void CreateFlash() 
     { 
      var flash = new Flash(); 
      flash.AdvancedOptions = PvtsFlashAdvancedOptionsEnum.AllProperties; 
     } 
    } 
} 

失敗NUnitのテストのためのコード:

また、失敗したコンソールアプリのため
using NUnit.Framework; 
using PvtsFlashLib; 

namespace Test 
{ 
    [TestFixture] 
    public class TestOfComNUnit 
    { 
     [Test] 
     public void CreateFlash() 
     { 
      var flash = new Flash(); 
      flash.AdvancedOptions = PvtsFlashAdvancedOptionsEnum.AllProperties; 
     } 
    } 
} 

コード:

using PvtsFlashLib; 

namespace ConsoleTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var flash = new Flash(); 
      flash.AdvancedOptions = PvtsFlashAdvancedOptionsEnum.AllProperties; 
     } 
    } 
} 

私は自分の質問に答えるために十分評判ポイントを持っていません。しかし、彼女はとにかくです:

何らかの理由で、COMオブジェクトはMTAThreadから作成できません。 MSTestのデフォルトはSTAThread、NUnit、コンソールのデフォルトはMTAThreadです。 ConsoleTest.Main()とTest.CreateFlash()に[STAThread]属性を適用することで問題は解決します。

答えて

1

この問題は、.NETコードとは異なるアパートメントで実行されているCOMオブジェクトに関連していることが判明しました。その観察結果を考慮すると、QueryInterfaceが失敗した最も可能性の高い理由は、ターゲットインターフェイスがアパートメント全体でマーシャリング可能でないためです。これは、.NETが関与していない場合でもCOMの問題となります。

.NETコードがCOMコンポーネントと一致するようにSTAスレッドで実行されていることを確認する最も簡単なソリューションが見つかりました。

ただし、インターフェイスでプロキシ/スタブマーシャラを使用できる場合は、MTAスレッドを使用することもできます。あなたがATLを使用していると述べたので、Application Settingsの「プロキシ/スタブコードのマージを許可する」オプションを設定するだけで済みます。

MSDNのInterface Marshalingのトピックも、参考になるかもしれません。

関連する問題