在 .Net 的 COM exe 中使用类
我有一个 .exe 文件,其中包含 COM 类 - 这些来自 C++,而不是 .net ComVisible
类型,
我想在我的 .net 项目中使用这些类,但我无法添加对exe的引用; 当我尝试时,我得到
DIALOG BOX:
---------------------------
Microsoft Visual Studio
---------------------------
A reference to 'C:\Program Files\blah\blah.exe'
could not be added. Please make sure that the
file is accessible, and that it is a valid
assembly or COM component.
---------------------------
OK
---------------------------
tlbimp 也失败了;
TLBIMP OUTPUT:
> tlbimp blah.exe
Microsoft (R) .NET Framework Type Library
to Assembly Converter 3.5.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.
TlbIml : error TI0000 : The input file
'c:\program files\blah\blah.exe' is not
a valid type library
但看起来确实有可用的 COM 类; 在我的 HKEY_CLASSES_ROOT
配置单元中,我可以看到不同 COM 类的条目;
REGISTRY ENTRY:
\HKEY_CLASSES_ROOT
\CLSID
\{456B14EA-4CCC-11D4-BB91-0020AFC894E9}
@="COM.Classname"
\InprocHandler32
@="ole32.dll"
\LocalServer32
"LocalServer32"=hex(7) ...
@="C:\\PROGRA~2\\blah\blah.exe"
\ProgID
@="COM.Classname"
有人知道我如何(甚至是否可以)在 .net 项目中使用这些 COM 类吗?
I have a .exe file I've been given which has COM classes inside it -- these are from C++, not .net ComVisible
types
I'd like to use those classes inside my .net project, but I can't add a reference to the exe; when I try I get
DIALOG BOX:
---------------------------
Microsoft Visual Studio
---------------------------
A reference to 'C:\Program Files\blah\blah.exe'
could not be added. Please make sure that the
file is accessible, and that it is a valid
assembly or COM component.
---------------------------
OK
---------------------------
tlbimp also fails;
TLBIMP OUTPUT:
> tlbimp blah.exe
Microsoft (R) .NET Framework Type Library
to Assembly Converter 3.5.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.
TlbIml : error TI0000 : The input file
'c:\program files\blah\blah.exe' is not
a valid type library
But it really looks as if there are COM classes available; in my HKEY_CLASSES_ROOT
hive I can see entries for the different COM clasess;
REGISTRY ENTRY:
\HKEY_CLASSES_ROOT
\CLSID
\{456B14EA-4CCC-11D4-BB91-0020AFC894E9}
@="COM.Classname"
\InprocHandler32
@="ole32.dll"
\LocalServer32
"LocalServer32"=hex(7) ...
@="C:\\PROGRA~2\\blah\blah.exe"
\ProgID
@="COM.Classname"
Anyone got a clue about how, and even if, I can use these COM classes from within a .net project?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可以通过三种方法分发类型库:单独在 .tlb 文件中分发,或者作为 .dll 或 .exe 文件内的嵌入资源。 但是,并不强制要求将类型库文件与 COM 组件一起分发。
通常,HKCR\CLSID{CLSID} 下会有一个 TypeLib 注册表项,该注册表项的默认值包含 typelib id。 (oleview.exe 对于追踪这些注册表项非常有用)。 如果您的注册表不包含 TypeLib 项,则很可能您的组件尚未随类型库一起分发。
tlbimp.exe 可以导入 .dll 或 .exe 文件内的任何嵌入式类型库资源,因此上面报告的错误向我表明您给定的可执行文件中没有嵌入式类型库。 您可以通过使用资源视图查看 exe 来确认这一点。 我忘记了 Windows SDK 资源查看器的名称,但您可以在这里找到一个免费的:MiTec Exe Explorer
如果 exe 没有 TYPELIB 资源,则无法创建 .net 互操作库。 然后,您唯一的选择是联系组件制造商并索取类型库。 如果这不可能,您可以使用后期绑定来调用组件。
There are three methods of distributing a type library: either separately in a .tlb file, or as an embedded resource inside a .dll or .exe file. However, it is not mandatory to distribute a type library file with a COM component.
Usually the there would be a TypeLib registry key underneath the HKCR\CLSID{CLSID}, which would have a default value containing the typelib id. (oleview.exe is very useful for tracking down these registry entries). If your registry does not contain a TypeLib key, then is is likely that your component has not been distributed with a type library.
tlbimp.exe can import any embedded type library resources inside .dll or .exe files, so the error it is reporting above indicates to me that there is no embeded type library in your given executable. You can confirm this by viewing the exe using a resource view. I have forgotten the name of the Windows SDK resource viewer, but you can find a free one here: MiTec Exe Explorer
If the exe does not have a resource of TYPELIB, then you cannot create a .net interop library. Your only option is then to contact the maker of the component and ask for a type lib. If this is not possible, you can use late binding to call the component.