dll にこのインターフェイスがあります (このコードはメタデータから Visual Studio に表示されます)。
#region Assembly XCapture.dll, v2.0.50727
// d:\svn\dashboard\trunk\Source\MockDiagnosticsServer\lib\XCapture.dll
#endregion
using System;
using System.Runtime.InteropServices;
namespace XCapture
{
[TypeLibType(4160)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
public interface IDiagnostics
{
[DispId(1)]
void GetStatusInfo(int index, ref object data);
}
}
だから私はそのようなクラスでCOMサーバーを作成しました:
[ComVisible(true)]
[Guid(SimpleDiagnosticsMock.CLSID)]
[ComDefaultInterface(typeof(IDiagnostics))]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleDiagnosticsMock : ReferenceCountedObject, IDiagnostics
{
public const string CLSID = "281C897B-A81F-4C61-8472-79B61B99A6BC";
// These routines perform the additional COM registration needed by
// the service. ---- stripped from example
void IDiagnostics.GetStatusInfo(int index, ref object data)
{
Log.Info("GetStatusInfo called with index={0}, data={1}", index, data);
data = index.ToString();
}
}
サーバーは正常に動作しているようで、VBScript からオブジェクトを使用できます。しかし、別の C# クライアントから使用しようとしました。
[STAThread]
static void Main(string[] args)
{
Guid mockClsId = new Guid("281C897B-A81F-4C61-8472-79B61B99A6BC");
Type mockType = Type.GetTypeFromCLSID(mockClsId, true);
IDiagnostics mock = (IDiagnostics)Activator.CreateInstance(mockType);
//var diag = mock as IDiagnostics;
object s = null;
mock.GetStatusInfo(3, ref s);
Console.WriteLine(s);
Console.ReadKey();
}
そして、それは失敗します
タイプ 'System.__ComObject' の COM オブジェクトをインターフェイス タイプ 'XCapture.IDiagnostics' にキャストできません。IID '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーのために失敗したため、この操作は失敗しました: サポートされているそのようなインターフェイスはありません (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) .
私は何を間違っていますか?
私も InvokeMember を使用しようとしましたが、ref-returned dataパラメータを取得できなかったことを除いて、それはちょっとうまくいきました。
編集:メイン プロシージャに STAThread 属性を追加しました。これで問題が解決するわけではありませんが、STAThreadが不要であるという確信がない限り、COM で STAThread を使用する必要があります。以下のHans Passantの回答を参照してください。