C#-编写COM服务器-客户端上未触发事件
我在C#中实现了一个COM服务器,它有一个vb6客户端 当触发我的事件时,处理程序总是空的——看起来vb6应用程序从未订阅我的事件 vb6应用程序是一个现有的第三方应用程序,似乎不会给出任何错误消息 从COM客户端->服务器,普通方法工作正常 我能做些什么来调试正在发生的事情吗?或者为什么我的活动不起作用 下面是我的代码的一个快速示例片段:C#-编写COM服务器-客户端上未触发事件,c#,.net,events,com,vb6,C#,.net,Events,Com,Vb6,我在C#中实现了一个COM服务器,它有一个vb6客户端 当触发我的事件时,处理程序总是空的——看起来vb6应用程序从未订阅我的事件 vb6应用程序是一个现有的第三方应用程序,似乎不会给出任何错误消息 从COM客户端->服务器,普通方法工作正常 我能做些什么来调试正在发生的事情吗?或者为什么我的活动不起作用 下面是我的代码的一个快速示例片段: [ComVisible(true), Guid(Constants.CLASS_IID), ProgId(Const
[ComVisible(true),
Guid(Constants.CLASS_IID),
ProgId(Constants.PROG_ID),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(IMyServiceEvents))]
public class MyClass : Control, IMyService, IMyServiceEvents
{
[DispId(1)]
public event MyEventHandler MyEvent;
//... also implements IMyService, which is working
}
[ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
Guid(Constants.EVENTS_IID)]
public interface IMyServiceEvents
{
[PreserveSig, DispId(1)]
void MyEvent([In]int Status);
}
[ComVisible(false)]
public delegate void MyEventHandler(int Status);
如果我尝试用我的C#com服务器替换/实现的现有ocx文件,事件将照常工作。它也是用vb6编写的,所以我的C#服务器中肯定有什么地方出错了
我还想补充一点,我尝试了ClassInterfaceType的所有3种设置,得到了相同的结果——尽管每次尝试都必须重新注册COM服务器
看看我生成的IDL,在我看来是正确的,而且一切似乎都与我试图重新创建的原始IDL非常相似,如果需要,我可以发布
更新:我拿出了旧的VisualStudio6,制作了一个VB6应用程序来测试我的C#COM服务器,它工作得很好
因此,我使用了一个免费的vb6反编译器,它可以将反编译的代码输出到vb6项目中,并在我想加载COM服务器的第三方应用程序上运行了它,结果发现它不起作用
我注意到他们的应用程序使用我的COM服务器作为设计器的控件,而我的测试程序只是以WithEvents的形式声明了一个成员变量。设计师在幕后有什么事情打破了这一点吗?如何使COM服务器ActiveX兼容?我还注意到VB6 ide不允许我将我的C#com服务器作为控件添加到工具箱中。我隐约记得自己也有这个错误,就像运行时不知道如何将com注册映射到您的事件一样 我回去看看我做了什么,唯一的区别是委托定义在我的COM类中,我也看到了在这个类中发生的情况 因此,请尝试在MyClass中移动MyEventHandler,如下所示:
[ComVisible(true),
Guid(Constants.CLASS_IID),
ProgId(Constants.PROG_ID),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(IMyServiceEvents))]
public class MyClass : Control, IMyService, IMyServiceEvents
{
[ComVisible(false)]
public delegate void MyEventHandler(int Status);
[DispId(1)]
public event MyEventHandler MyEvent;
//... also implements IMyService, which is working
}
[ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
Guid(Constants.EVENTS_IID)]
public interface IMyServiceEvents
{
[PreserveSig, DispId(1)]
void MyEvent([In]int Status);
}
我是从控件而不是用户控件派生出来的,我看到了一个在C#中实现ActiveX控件的例子,这让我想到了这一点
显然,UserControl实现了一些接口,使其能够正常工作。。。谁知道…您可能忘了添加 [程序集:Guid(“…”)] 对于您的项目,这意味着每次重新编译C#项目时COM中的TypeLib ID都会更改
如果没有该属性,编译器将生成不同的typelibrary,但某些COM函数在没有匹配库ID的情况下工作。我找到了一个修复方法,允许我使用从控件继承的自定义控件(与UserControl相反) 在代码编辑器中,添加WithEvents变量的声明:
Dim WithEvents ControlNameEvents As ControlLibrary.ControlName
在表单_Load事件处理程序中,添加以下代码以初始化WithEvents变量:
Private Sub Form_Load()
Set ControlNameEvents = Me.ControlNameOnVB6Form
End Sub
添加代码以在WithEvents变量的事件处理程序中处理自定义事件:
Private Sub ControlNameEvents_MyCustomEvent()
MsgBox("My custom event fired")
End Sub
来源:尝试得很好,但没有成功。我想知道他们的vb6代码是否做得不正确,不允许.Net CCW处理该事件。我也尝试过几种方法,添加一个snk,将程序集放在GAC中,而不是使用regasm/codebase,但似乎没有任何效果。然而,标准方法很好用。这是很久以前的事了。但我不认为这是问题所在。