我正在用 C# 编写一个(共享)Word 加载项,并希望通过 COMAddIn 类的 Object 属性公开一个对象来与它进行通信。
因为我希望我的代码在 UI 线程上执行,所以我从 StandardOleMarshalObject 类派生了我的加载项和公开对象。这应该照顾这里和这里描述的编组。
但是通过这样做,当我针对 .NET 2.0 或 .NET 4.0 进行编译时,我会得到不同的行为。在针对 .NET 4.0 进行编译时,我公开的对象是 __ComObject 类型,并且可以将其自身转换为我公开的可共享定义的接口。这反过来又让我可以调用对象上的方法并完美地工作。
在针对 .NET 2.0 进行编译时,公开的对象是 __TransparentProxy 类型。这也可以转换为我的界面,但是当我尝试调用一个方法时,它会抛出一个 System.Runtime.Remoting.RemotingException 并显示以下消息:
此远程代理没有通道接收器,这意味着服务器没有注册的正在侦听的服务器通道,或者此应用程序没有合适的客户端通道与服务器通信。
当我不从 StandardOleMarshalObject 继承时,它似乎确实可以工作,但是我的代码将在任意 RPC 线程上执行,这不是我想要的。
我搜索了互联网,但无法找到解决方案或原因,这在 .NET 2.0 中不起作用。我确实发现了一些类似的问题,但它们似乎都解决了 Excel。
目前我还没有切换到 .NET 4.0 的位置,所以我真的希望这可以为 .NET 2.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
}
}