2012-07-04 4 views
0

У меня есть веб-сайт ASP.NET MVC3, который должен работать с COM-плагинами. Для этого мне нужно каким-то образом определить интерфейс. Насколько я понимаю (я не эксперт COM) это можно сделать либо в .NET, либо экспортировать его с помощью tlbexp.exe или idl-> midl-> tlbimp.COM-интерфейс .net plugin framework

Я пошел первым путем (с tlbexp). Я тоже пробовал IDL, но безрезультатно (по какой-то причине он мог применить реализованный COM-объект к интерфейсу tlbimp' в .NET).

Этот сценарий был бы простым, если мой интерфейс не есть событие на нем:

[ComVisible(true)] 
[Guid("EFCFB783-0225-4D45-94CB-9A26B7CC19AF")] 
public delegate void ItemStatusChanged(string itemGuid, string itemStatus); 

[ComVisible(true)] 
[Guid("35202AE5-392D-4015-993D-29966DA5DE31")] 
[InterfaceType(ComInterfaceType.InterfaceIsDual)] 
public interface ICOMOutputPlugin 
{ 
    void Method1(string arg); 
    void Method2(string arg); 
    event ItemStatusChanged ItemStatusChanged; 
} 

[ComVisible(true)] 
[Guid("93862C43-503C-4C96-9BAE-944F1087AB77")] 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface ICOMOutputPluginEvents 
{ 
    void ItemStatusChanged(string itemGuid, string itemStatus); 
} 

экспортировать это в TLB с Tlbexp.exe и зарегистрировать .TLB с regtlibv12. Только библиотека этого типа будет использоваться разработчиками плагинов для импорта интерфейсов.

Теперь у меня есть проект C++, который будет плагин, добавить в VS2010 новый объект простой ATL и изменить IDL на:

importlib("stdole2.tlb"); 
importlib("MyExp.tlb"); 

[ 
    uuid(E09BC67A-4192-4CA3-8FD0-5CBFC69B43AC)  
] 
coclass DumpToFileOutputPlugin 
{ 
    [default] interface ICOMOutputPlugin; 
    [default, source] dispinterface ICOMOutputPluginEvents; 
}; 

Моя первая проблема здесь в том, что по какой-то причине я не мог добавьте точку подключения «обычный путь» с помощью мастера классов. Он просто не показывает никаких исходных интерфейсов, когда я направляю его на MyExp.tlb. Поэтому я сделал это вручную (использовал другой .tlb и переименовал все).

Так что теперь у меня есть COM-объект с этими 2 методами:

STDMETHOD(add_ItemStatusChanged)(_ItemStatusChanged* value); 
STDMETHOD(remove_ItemStatusChanged)(_ItemStatusChanged* value); 

На стороне .NET менеджер плагин конкретизирует плагины, как это:

Type type = Type.GetTypeFromProgID(progID); 
comObject = Activator.CreateInstance(type) as ICOMOutputPlugin; 
comObject.ItemStatusChanged += (guid, status) => ItemStatusChanged(guid, status); 

последняя строка чудесным образом называет add_ItemStatusChanged способ на моем COM-объекте.

Здесь я застрял, что я должен использовать в этом методе? моя текущая реализация:

HRESULT CDumpToFileOutputPlugin::add_ItemStatusChanged(_ItemStatusChanged* value) 
{ 
     DWORD cookie; 
     HRESULT ret = Advise(value, &cookie); 
     _com_error err(ret); 
     LPCTSTR errMsg = err.ErrorMessage(); 
     return ret; 
} 

RET = CONNECT_E_CANNOTCONNECT (0x80040202) и ERRMSG говорит "IDispatch ошибки # 2". Очевидно, Advise ожидает, что COM-объект передан для реализации интерфейса точки подключения ICOMOutputPluginEvents, который передал делегат объекту ... что я могу сделать?

Я делаю подписку на событие на стороне .NET неправильно или обработчик добавления?

Любая помощь, как решить эту проблему, будет оценена по достоинству.

ответ

-1

Не используйте «события» в плагине COM для ASP.Net, просто используйте методы, которые вы вызываете. То есть метод, называемый OnEventName, а не событие.

COM-события - это не совсем то, что нужно для обработки обратных почтовых сообщений.

+0

моя проблема не имеет ничего общего с ASP.NET, это просто проблема COM-взаимодействия, любое другое приложение .net будет делать, чтобы проиллюстрировать проблему – Bond

+0

@Bond, вам не хватает точки. Вам не нужны события. Вы просто не нуждаетесь в них, поэтому избегайте проблемы взаимодействия COM, НЕ ИСПОЛЬЗУЯ СОБЫТИЯ. Просто выполняйте функции с EVENT-LIKE NAMES и вызывайте их, когда происходит событие. Это связано с тем, что COM-события являются РАЗЛИЧНЫМИ BEASTS и являются болью для подключения к ASP.NET, как вы только что узнали. – Ben

+0

Тот факт, что tlbexp экспортирует событие в пару метода добавления/удаления и эти методы вызывается, когда я подписываюсь на событие на стороне .NET, заставляет меня думать, что должен быть какой-то способ заставить его работать. – Bond

Смежные вопросы