简体   繁体   English

基于COM的.net插件框架

[英]COM based .net plugin framework

I have an ASP.NET MVC3 website which has to work with COM plugins. 我有一个必须与COM插件一起使用的ASP.NET MVC3网站。 In order to do that I need to define an interface somehow. 为了做到这一点,我需要以某种方式定义一个接口。 As far as I understand(I'm not a COM expert) this can be done either in .NET and export it with tlbexp.exe or idl->midl->tlbimp. 据我了解(我不是COM专家),可以在.NET中完成此操作,并使用tlbexp.exe或idl-> midl-> tlbimp将其导出。

I have gone the first way(with tlbexp). 我已经走了第一种方法(使用tlbexp)。 I tried IDL too but to no avail(for some reason could cast the implementing COM object back to the tlbimp'ed interface in .NET). 我也尝试了IDL,但无济于事(由于某些原因,可能会将实现的COM对象转换回.NET中的tlbimp'ed接口)。

This scenario would be simple if my interface didn't have an event on it: 如果我的界面上没有事件,这种情况将很简单:

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

I export this to tlb with tlbexp.exe and register the .tlb with regtlibv12. 我使用tlbexp.exe将其导出到tlb,并使用regtlibv12注册.tlb。 Only this type library will be used by the plugin developers to import the interfaces. 插件开发人员将仅使用此类型库来导入接口。

Now I have a C++ project which will be a plugin, I add in VS2010 new simple ATL object and change the IDL to: 现在我有一个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;
};

My first problem here was that for some reason I couldn't add the connection point the 'normal way' via class wizard. 我的第一个问题是由于某种原因,我无法通过类向导以“正常方式”添加连接点。 It simply doesn't show any source interfaces when I direct it to my MyExp.tlb. 当我将其定向到MyExp.tlb时,它根本不显示任何源接口。 So I did that manually(used another .tlb and renamed everything). 因此,我手动执行了此操作(使用了另一个.tlb并重命名了所有内容)。

So now I have the COM object with these 2 methods: 所以现在我有了这两种方法的COM对象:

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

On the .NET side the plugin manager instantiates the plugins like this: 在.NET方面,插件管理器以如下方式实例化插件:

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

the last line miraculously calls the add_ItemStatusChanged method on my COM object. 最后一行奇迹般地在我的COM对象上调用add_ItemStatusChanged方法。

Here I'm stuck, what should I don in this method? 在这里,我被卡住了,这种方法应该怎么做? my current implementation is: 我当前的实现是:

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) and errMsg says "IDispatch error #2". ret = CONNECT_E_CANNOTCONNECT(0x80040202)并且errMsg说“ IDispatch错误#2”。 Apparently Advise expects the COM object passed to implement the connection point interface ICOMOutputPluginEvents which the delegate passed object does not... what can I do? 显然,Advise希望传递的COM对象实现连接点接口ICOMOutputPluginEvents ,而委托传递的对象不ICOMOutputPluginEvents该接口...我该怎么办?

Am I doing the subscription to the event on the .NET side wrong or the add handler? 我是在.NET端对事件进行订阅错误还是添加了处理程序?

Any help how to solve this would be appreciated. 任何帮助如何解决这个问题将不胜感激。

Don't use "events" in a COM plugin for ASP.Net, just have methods that you call. 不要在ASP.Net的COM插件中使用“事件”,只需使用您调用的方法即可。 Ie a method called OnEventName rather than an event. 即称为OnEventName的方法,而不是事件。

COM events are just not the right kind of thing for handling web form postbacks. COM事件不是处理Web表单回发的正确方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM