【问题标题】:C# to VB6 COM events (“object or class does not support the set of events”), but differentC# 到 VB6 COM 事件(“对象或类不支持事件集”),但不同
【发布时间】:2020-04-30 10:00:35
【问题描述】:

我知道一个 10 年前的问题与这个问题的标题相同,但我已经仔细检查过,我没有错误地使用代表姓名。这是一个不同的问题。

在工作中,我们有一个旧的 VB6 应用程序,我需要教授新的(呃)技巧。我要做的第一件事是让它从一个用 C# 编写的 .Net COM 可见 DLL 调用方法。我有那个工作。现在我需要让它处理来自同一个 DLL 的传入进度通知事件。我昨天问了一个类似的问题,其中 VB6 IDE 甚至没有看到 DLL 有事件要提供。通过正确装饰 C# 接口和类解决了这个问题。

首先,C#代码:

namespace NewTricksDLL
{
    [ComVisible(true)]
    [Guid("16fb3de9-3ffd-4efa-ab9b-0f4117259c75")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ITransfer
    {
        [DispId(2)]
        string SendAnEvent();
    }

    [ComVisible(true)]
    [Guid("16fb3de9-3ffd-4efa-ab9b-0f4117259c74")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IManagedEventsToCOM
    {
        [DispId(2)]
        void NotificationEvent();

    }

    [ComVisible(true)]
    [Guid("dcf177ab-24a7-4145-b7cf-fa06e892ef21")]
    [ComSourceInterfaces(typeof(IManagedEventsToCOM))]
    [ProgId("ADUTransferCS.NewTricks")]
    public class NewTricks : ITransfer
    {
        public delegate void NotificationEventHandler();
        public event NotificationEventHandler NotifificationEvent;

        public string SendAnEvent()
        {
            if (NotifificationEvent != null)
                NotifificationEvent();           
        }
    }
}

现在我尝试在 VB6 中使用它。请注意,_tricky_NotificationEvent 事件处理程序是由 IDE 通过从左侧下拉列表中选择 _tricky 和从右侧下拉列表中选择 NotificationEvent 生成的,因此我知道此事件对 VB6 IDE 可见。

Option Explicit

Public WithEvents _tricky As NewTricksDLL.NewTricks

Private Sub Command1_Click()
    ' The next line fails with 'Object or class does not support the set of events'
    Set _tricky = CreateObject("NewTricksDLL.NewTricks")
    ' Execution never makes to the next line
    _tricky.SendAnEvent()

End Sub

Private Sub _tricky_NotificationEvent()
    ' This handler was auto generated by the IDE
End Sub

【问题讨论】:

  • 这能回答你的问题吗? Exposing .NET events to COM?
  • @GSerg 不,因为它看起来像我已经拥有的。它确实包括通过接口公开异步任务,这是我接下来需要做的,所以谢谢你。 :)
  • 虽然你错过了[ClassInterface(ClassInterfaceType.None)],但我不确定它是否重要。
  • 似乎没有。我以前试过(然后又试了一次),但没有帮助。
  • 给出错误的确切行是什么?

标签: com vb6 com-interop


【解决方案1】:

如果你使用CreateObject,我相信它会创建一个 Object 类型的对象。你应该简单地使用New来创建对象:

Set _tricky = New NewTricksDLL.NewTricks

由于您将变量声明为 WithEvents,因此您不能只使用 As New NewTricksDLL.NewTricks 声明它,我想您可能已经尝试过。

【讨论】:

  • 这绝对值得一试,但我不确定这是否是问题所在。由于_tricky 定义了正确的类型,我认为CreateObject() 的结果应该正确使用。也就是说,除非它确实没有返回预期类型的​​对象。
  • NewCreateObject都导致'Object or class does not support the set of events'。同样,ObjectBrowser 确实显示了该程序集中的事件。
【解决方案2】:

希望这会有所帮助 - 这是您要求的最基本的 VB.net 实现:VB6 可使用的 COM 接口,一个事件,一种方法。

Option Explicit On
Option Strict On

<ComClass(newTricks.ClassId, newTricks.InterfaceId, newTricks.EventsId)>
Public Class newTricks

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "386d540d-f8b8-46e1-939d-7b69dd5eff0a"
    Public Const InterfaceId As String = "78b4036e-86a0-4671-997d-da5a33bf026f"
    Public Const EventsId As String = "7b0fa5b5-b45e-4db2-9282-c06e09852161"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    Public Event NotificationEvent()

    Public Sub SendAnEvent()
        RaiseEvent NotificationEvent()
    End Sub
End Class

这是通过启动一个新项目(Windows 类库)创建的,从项目中删除自动创建的 Class1.vb,添加一个 COM 类项,将其重命名为 NewTricks。然后添加事件声明和子声明和代码;还添加了选项语句。构建项目。

从这个 VB6 代码中成功使用了它。单击该按钮导致“事件触发”被写入即时窗口。使用NewCreateObject 方法来创建对newTricks 的引用是成功的。

Option Explicit

Private WithEvents oTricks As NewTricksDll.newTricks

Private Sub Command1_Click()

  Set oTricks = New NewTricksDll.newTricks
  'Set oTricks = CreateObject("NewTricksDll.newTricks")

  oTricks.SendAnEvent

End Sub

Private Sub oTricks_NotificationEvent()
  Debug.Print "Event fired"
End Sub

这是 VB.net 代码对应的 C# 代码,由 https://converter.telerik.com/ 直接转换

using Microsoft.VisualBasic;

[ComClass(newTricks.ClassId, newTricks.InterfaceId, newTricks.EventsId)]
public class newTricks
{

    // These  GUIDs provide the COM identity for this class 
    // and its COM interfaces. If you change them, existing 
    // clients will no longer be able to access the class.
    public const string ClassId = "386d540d-f8b8-46e1-939d-7b69dd5eff0a";
    public const string InterfaceId = "78b4036e-86a0-4671-997d-da5a33bf026f";
    public const string EventsId = "7b0fa5b5-b45e-4db2-9282-c06e09852161";

    // A creatable COM class must have a Public Sub New() 
    // with no parameters, otherwise, the class will not be 
    // registered in the COM registry and cannot be created 
    // via CreateObject.
    public newTricks() : base()
    {
    }

    public event NotificationEventEventHandler NotificationEvent;

    public delegate void NotificationEventEventHandler();

    public void SendAnEvent()
    {
        NotificationEvent?.Invoke();
    }
}

我没有尝试过这个 C# 代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 2013-12-19
    • 2011-07-13
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多