C#で(共有)Wordアドインを作成していて、COMAddInクラスのObjectプロパティを介してオブジェクトを公開することで通信したいと考えています。
コードをUIスレッドで実行したいので、StandardOleMarshalObjectクラスからアドインと公開オブジェクトを派生させます。これにより、こことここで説明されているようにマーシャリングが処理されます。
ただし、これを行うと、.NET2.0または.NET4.0に対してコンパイルしたときに異なる動作が発生します。.NET 4.0に対してコンパイルする場合、公開されたオブジェクトは__ComObject型であり、公開されている定義済みのインターフェイスにキャストできます。これにより、オブジェクトのメソッドを呼び出すことができ、完全に機能します。
.NET 2.0に対してコンパイルする場合、公開されるオブジェクトのタイプは__TransparentProxyです。これはインターフェイスにキャストすることもできますが、メソッドを呼び出そうとすると、次のメッセージとともにSystem.Runtime.Remoting.RemotingExceptionがスローされます。
このリモートプロキシにはチャネルシンクがありません。つまり、サーバーにリッスンしているサーバーチャネルが登録されていないか、このアプリケーションにサーバーと通信するための適切なクライアントチャネルがありません。
StandardOleMarshalObjectから継承しない場合は機能しているように見えますが、コードは任意のRPCスレッドで実行されますが、これは私が探しているものではありません。
インターネットを検索しましたが、.NET2.0でこれが機能しない解決策や理由を見つけることができませんでした。私はいくつかの同様の問題を見つけましたが、それらはすべてExcelに対処しているようです。
現時点では、私は.NET 4.0に切り替える立場にないので、これが.NET2.0で解決できることを本当に望んでいます。
誰かがこの問題の解決策、または少なくとも説明を持っていますか?
これが私のテストコードです:
[ComVisible(true)][Guid("...")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IService
{
void Hello();
}
[ComVisible(true)][Guid("...")]
[ClassInterface(ClassInterfaceType.None)]
public class MyService : StandardOleMarshalObject, IService
{
public void Hello()
{
MessageBox.Show("Hello");
}
}
public class MyAddIn : StandardOleMarshalObject, IDTExtensibility2
{
public void OnConnection(object application, ext_ConnectMode connectMode,
object addInInst, ref Array custom)
{
_service = new MyService();
((COMAddIn)addInInst).Object = _service;
}
//Rest of the IDTExtensibility2 implementation
}
public class Test
{
public static void Main(string[] args)
{
Application app = new Application();
app.Visible = true;
COMAddIn addIn = app.COMAddIns.Item("MyAddin");
IService service = addIn.Object as IService;
if (service != null)
service.Hello(); // <-- RemotingException happening here
}
}