2012-07-04 68 views
0

我有一個ASP.NET MVC3網站必須使用COM插件。爲了做到這一點,我需要以某種方式定義一個接口。據我所知(我不是一個COM專家),這可以在.NET中完成,並用tlbexp.exe或idl-> midl-> tlbimp導出。基於COM的.net插件框架

我走了第一條路(用tlbexp)。我也嘗試過IDL,但無濟於事(出於某種原因可以將實現COM對象轉換回.NET中的tlbimp接口)。

此方案將是簡單的,如果我的界面沒有它的事件:

[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); 
} 

我這個出口與tlbexp.exe到TLB和註冊regtlibv12的.TLB。 只有這個類型的庫將被插件開發者用來導入接口。

現在我有一個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並重命名所有內容)。

所以現在我有這2種方法的COM對象:

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); 

最後一行奇蹟般地調用我的COM對象上的方法add_ItemStatusChanged

在這裏,我卡住了,我應該用什麼方法在這種方法?我目前的實現是:

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」。 顯然建議期望傳遞的COM對象實現委託傳遞對象的連接點接口ICOMOutputPluginEvents不......我該怎麼辦?

我是否訂閱了.NET上的事件錯誤或添加處理程序?

任何幫助如何解決這個將不勝感激。

回答

-1

不要在ASP插件的COM插件中使用「事件」,只需調用方法即可。即一種稱爲OnEventName的方法而不是事件。

COM事件對於處理web表單回發並不是正確的。

+0

我的問題與ASP.NET無關,它只是一個COM Interop問題,任何其他.net應用程序都會解釋這個問題 – Bond

+0

@Bond,您錯過了這一點。你不需要事件。你只是不需要它們,所以通過不使用事件來避免COM互操作問題。只需具有EVENT-LIKE NAMES的功能,並在事件發生時調用它們。這是因爲COM事件是不同的BEASTS,並且正如你剛纔所瞭解的那樣,很難在ASP.NET中建立連接。 – Ben

+0

事實上,tlbexp將事件導出到add/remove方法對中,並且在我訂閱.NET端事件時調用這些方法,這讓我認爲必須有某種方法才能使其工作。 – Bond