Я пишу (совместно используемую) надстройку Word на C # и хочу связаться с ней, выставив объект через свойство Object класса COMAddIn.
Поскольку я хочу, чтобы мой код выполнялся в потоке пользовательского интерфейса, я извлекаю свою надстройку и открытый объект из класса 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
}
}