Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WithEvents错误使来自.NET组件的COM事件下沉_.net_Vba_Com_Vb6_Com Interop - Fatal编程技术网

WithEvents错误使来自.NET组件的COM事件下沉

WithEvents错误使来自.NET组件的COM事件下沉,.net,vba,com,vb6,com-interop,.net,Vba,Com,Vb6,Com Interop,我试图在.NET中引发一个事件,并让VBA应用程序通过COM拾取它。在使我的事件在类型库中正确显示方面非常有帮助 在VBA方面,一切看起来都是合法的。我有一个声明为“WithEvents”的对象变量,IDE允许我添加事件处理程序,编译器不会抱怨。但是,在运行时,当我使用New来创建我根据帮助文件获得的对象时,这意味着:“您试图将WithEvents变量与无法作为指定事件集的事件源的组件一起使用。” 我真的不知道为什么。我不认为我违反了帮助文件也解释的实现规则。下面是类型库的IDL(幸运的是它很短

我试图在.NET中引发一个事件,并让VBA应用程序通过COM拾取它。在使我的事件在类型库中正确显示方面非常有帮助

在VBA方面,一切看起来都是合法的。我有一个声明为“WithEvents”的对象变量,IDE允许我添加事件处理程序,编译器不会抱怨。但是,在运行时,当我使用New来创建我根据帮助文件获得的对象时,这意味着:“您试图将WithEvents变量与无法作为指定事件集的事件源的组件一起使用。”

我真的不知道为什么。我不认为我违反了帮助文件也解释的实现规则。下面是类型库的IDL(幸运的是它很短)。有人能看到导致这种情况的类型库有什么问题吗

编辑:--------------------------------

记得我在几个版本之前就有过这个组件的COM版本,我比较了它的IDL,注意到在它上面,两个接口都有标记。这是否与WithEvents故障相关?当我使用该组件而不是新组件时,它不会在“新建”时失败,并正确地接收事件

我看到的唯一其他区别是事件接口的属性和双下划线命名(为什么这两者都很重要?)

.tlb from.NET

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: Drawing Locator.tlb

[
  uuid(4ABD3AAB-CA6A-48D6-8E4E-8082645A0F05),
  version(1.0),
  custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, "Drawing Locator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e02c23b3671cff4d")

]
library Drawing_Locator
{
    // TLib :     // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
    importlib("mscorlib.tlb");
    // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("stdole2.tlb");

// Forward declare all types defined in this typelib
interface IDrawingFinder;
dispinterface IDrawingFinderEvents;

typedef [uuid(565D6F5A-13BF-4794-AC35-3ECC4329B280), version(1.0)    ,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Drawing_Locator.FileTypes")    
]
enum {
    FileTypes_Tiff = 0,
    FileTypes_Acad = 1
} FileTypes;

[
  uuid(78B2A29B-C289-4D65-B373-C345AD06BD31),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Drawing_Locator.DrawingFinder")
]
coclass DrawingFinder {
    interface _Object;
    [default] interface IDrawingFinder;
    [default, source] dispinterface IDrawingFinderEvents;
};

[
  odl,
  uuid(21DBD6E1-D04F-4335-B189-5B49EB960605),
  version(1.0),
  dual,
  oleautomation,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Drawing_Locator.IDrawingFinder")    

]
interface IDrawingFinder : IDispatch {
    [id(0x60020000)]
    HRESULT GetFiles(
                    [in] BSTR PartNumber, 
                    [in] FileTypes FileType, 
                    [in] VARIANT_BOOL OpenFiles, 
                    [out, retval] SAFEARRAY(BSTR)* pRetVal);
    [id(0x60020001)]
    HRESULT RegisterTiffToImaging();
};

[
  uuid(60314738-04D1-4B4A-BC39-6A81DE24A13B),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Drawing_Locator.IDrawingFinderEvents")    

]
dispinterface IDrawingFinderEvents {
    properties:
    methods:
        [id(0x00000001)]
        void PartNumberChanged([in] BSTR NewPartNumber);
        [id(0x00000002)]
        void Searching([in, out] VARIANT_BOOL* CancelSearch);
};
};
在.NET端的代码:

Imports System.Runtime.InteropServices

<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsDual)>
<Guid("21DBD6E1-D04F-4335-B189-5B49EB960605")>
Public Interface IDrawingFinder

Function GetFiles(ByVal PartNumber As String, ByVal FileType As FileTypes, ByVal OpenFiles As Boolean) As <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_BSTR)> String()

Sub RegisterTiffToImaging()

End Interface



<ComVisible(True)>
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>
<Guid("60314738-04D1-4B4A-BC39-6A81DE24A13B")>
Public Interface IDrawingFinderEvents

<System.Runtime.InteropServices.DispId(1)>
Sub PartNumberChanged(ByVal NewPartNumber As String)

<System.Runtime.InteropServices.DispId(2)>
Sub Searching(ByRef CancelSearch As Boolean)

End Interface

<ComVisible(True)>
<GuidAttribute("565D6F5A-13BF-4794-AC35-3ECC4329B280")>
Public Enum FileTypes
Tiff
Acad
End Enum

<System.Runtime.InteropServices.ComVisible(False)>
Public Delegate Sub OnPartNumberChanged(ByVal NewPartNumber As String)
<System.Runtime.InteropServices.ComVisible(False)>
Public Delegate Sub OnSearching(ByRef CancelSearch As Boolean)


<ComVisible(True)>
<ClassInterface(ClassInterfaceType.None)>
<ComDefaultInterface(GetType(Drawing_Locator.IDrawingFinder))>
<ComSourceInterfaces(GetType(Drawing_Locator.IDrawingFinderEvents))>
<GuidAttribute("78B2A29B-C289-4D65-B373-C345AD06BD31")>
Public Class DrawingFinder
Implements IDrawingFinder


Public Event PartNumberChanged As OnPartNumberChanged

Public Event Searching As OnSearching


'Event PartNumberChanged(ByVal NewPartNumber As String)
'Event Searching(ByRef CancelSearch As Boolean)

Private Declare Sub SHAddToRecentDocs Lib "shell32.dll" (ByVal uFlags As Integer, ByVal pv As String)
Private Const SHARD_PATH As Integer = 2

Dim worker As BackgroundWorker
Dim eventargs As DoWorkEventArgs




Public Function GetFiles(ByVal PartNumber As String, ByVal FileType As FileTypes, ByVal OpenFiles As Boolean) As String() Implements IDrawingFinder.GetFiles

End Sub

End Class

我将编译.net版本,然后使用OLEVIEW从.net和COM VB6版本生成TLB的代码

然后用BeyondCompare或Araxis之类的方法比较它们

让所有的guid都排列好,然后寻找其他的差异

发布的内容并没有让我感到意外,但我花了大量时间比较TLB,以获得“恰到好处”的.net版本

我不确定发布链接的礼节,但不久前我做了一个项目,它在VB6中启用了书签和断点保存。它是一个VB.net项目,为VB6 IDE生成了一个COM加载项,因此其中有很多COM互操作示例代码

在这里查看:


什么也没跳出来。当您对COM服务器进行增量更改时,刷新类型库以使其使用更新版本是很重要的。在VBA环境中,删除类型库引用并将其添加回。@HansPassant请在编辑的问题中查看关于“非扩展性”的问题?[nonextensible]是一个属性,表明[dual]接口的两侧相同。也就是说,通过IDIspatch可用的每个方法也可以通过本机接口使用。这不应该导致事件处理本身的问题。我的猜测是Hans建议的,您仍然注册了旧DLL,而新DLL的类型库不兼容。请尝试从VBA项目中删除该组件,取消注册旧组件,或者关闭VB以便更好地执行操作,注册新组件,然后再次添加该组件。
// typelib filename: DrawingFinder.dll

[
uuid(D11F3F87-F149-4060-81D3-F46A90DA28CB),
version(1.0),
helpstring("Finds and Opens Engineering Drawings"),
custom(50867B00-BB69-11D0-A8FF-00A0C9110059, 9782)

]
library DrawingSearch
{
// TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("stdole2.tlb");

// Forward declare all types defined in this typelib
interface _DrawingFinder;
dispinterface __DrawingFinder;

[
  odl,
  uuid(A0AB1327-59A7-45E0-8992-92DB8253368B),
  version(1.0),
  hidden,
  dual,
  nonextensible,
  oleautomation
  ]
  interface _DrawingFinder : IDispatch {
    [id(0x60030000)]
    HRESULT OpenAcadDwgs([in] BSTR PN);
    [id(0x60030001)]
    HRESULT OpenImageFiles([in] BSTR PN);
    [id(0x60030002)]
    HRESULT GetAcadDwgs(
                    [in] BSTR PN, 
                    [out, retval] SAFEARRAY(BSTR)* );
    [id(0x60030003)]
    HRESULT GetImageFiles(
                    [in] BSTR PN, 
                    [out, retval] SAFEARRAY(BSTR)* );
};

[
  uuid(95E5F4E3-6A45-4B60-845B-3A78E75A8319),
  version(1.0)
]
coclass DrawingFinder {
    [default] interface _DrawingFinder;
    [default, source] dispinterface __DrawingFinder;
};

[
  uuid(BB78905B-297B-4D7C-80B0-3297D4B07AFE),
  version(1.0),
  hidden,
  nonextensible
]
dispinterface __DrawingFinder {
    properties:
    methods:
        [id(0x00000001)]
        void Searching([in, out] VARIANT_BOOL* Cancel);
        [id(0x00000002)]
        void PartNumberChanged([in] BSTR FormattedPN);
};

typedef [uuid(4F3E20EC-EE21-40E8-813F-9292605EF941), version(1.0)]
enum {
    errArgument_OutOfRange = 0x80040001,
    errDrawing_FolderNotFound = 0x80040002,
    errDrawing_FileNotFound = 0x80040003,
    errDrawing_BadShortcut = 0x80040004,
    errDrawing_ViewerNotFound = 0x80040005,
    errDrawing_Open = 0x80040006,
    errDrawing_SearchCancelled = 0x80040007,
    errAcad_NotAvailable = 0x80040008
} ErrorTypeEnum;
};