C# 包装器接口错误:E_NOINTERFACE
我正在尝试为我拥有的 COM 对象(名为 SC_COM.dll)生成 C# 包装器,但在将其与 Visual Studio 2008(运行 Vista)链接时遇到一些问题。 我需要使用 COM DLL 执行此免注册操作 - 我正在使用清单文件让 Visual Studio 了解 SC_COM.dll,并且这似乎有效。 我使用 TblImp.exe 生成一个类型库 (SC_COMtlb.dll),我在 Visual Studio 2008 中引用该库,这样我就可以与我需要的 DLL 进行早期绑定。 DLL 与清单和可执行文件位于同一目录中。
问题如下:当我实例化该对象并尝试在 C# 中调用其方法之一时,它会抛出以下错误:
检测到错误:无法将类型“SC_COMtlb.SCAccessObjClass”的 COM 对象强制转换为接口类型“SC_COMtlb.ISCUploader”。 此操作失败,因为对 IID 为“{C677308A-AC0F-427D-889A-47E5DC990138}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE)) .
我不完全确定这个错误意味着什么——我已经搜索了错误代码,它似乎是一个相对常见的 C# 错误。 那么我是否会在这里以错误的方式链接 COM 对象,或者我可能缺少其他一些重要步骤?
我可能应该注意到,我不完全确定我生成的类型库(S\C_COMtlb.dll)如何知道实际的 COM DLL 在哪里,因为它没有在系统中注册 - 我假设它只是看起来相同目录。 这可能是问题所在吗?如果是,我怎样才能更好地将两者联系起来?
I am trying to produce a C# wrapper for a COM object that I have (named SC_COM.dll), but am having some issues linking it with Visual Studio 2008 (running Vista). I need to do this registration-free with the COM DLL--I'm using a manifest file to let Visual Studio know about SC_COM.dll, and that appears to be working. I used TblImp.exe to generate a type library (SC_COMtlb.dll) that I'm referencing in Visual Studio 2008 so I can do early binding with the DLL that I need. The DLLs are both in the same directory as the manifest and the executable.
Here's the issue: When I instantiate the object and try and call one of its methods in C#, it throws the following error:
Error detected: Unable to cast COM object of type 'SC_COMtlb.SCAccessObjClass' to interface type 'SC_COMtlb.ISCUploader'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{C677308A-AC0F-427D-889A-47E5DC990138}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
I'm not entirely certain what this error means--I've done a search on the error code, and it appears to be a relatively general C# error. So am I going about linking the COM object the wrong way here, or is there some other important step I may be missing?
I should probably note that I'm not entirely sure how the type library (S\C_COMtlb.dll) that I produced knows where the actual COM DLL is, since it's not registered with the system--I assume it just looks in the same directory. Could this potentially be the issue, and if so, how can I better link the two?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试将其添加到您的 App.exe.manifest 中:
TLBID 可以从 Visual Studio 生成的 Native.Namespace.Assembly.Name.manifest 中找到,如下所示:
我已经为此苦苦挣扎了一段时间,但我发现这些有用的参考资料并将其拼凑在一起,它对我有用:
Try adding this to your App.exe.manifest:
Where TLBID can be found from your Visual Studio generated Native.Namespace.Assembly.Name.manifest, looking like this:
I was banging my head against this for quite some time, but I found these helpful references and pieced it together and it's working for me:
哪个版本的 Windows? 从 Windows Vista 开始,内部清单会覆盖外部清单。 默认情况下,C# 可执行文件具有内部清单,这意味着您的
whatever.exe.manifest
文件将被忽略。如果您转到 C# EXE 的属性页,您将看到“应用程序选项卡”上有一个“图标和清单”部分。 将“Manifest”设置为清单文件的名称,它将被嵌入而不是默认的。
如果这不起作用,您可能需要使用 MT.EXE 执行一些构建后步骤,以便将外部清单与默认内部清单合并,并将合并的清单放回到 .EXE 文件中。
Which version of Windows? Since Windows Vista, an internal manifest overrides an external manifest. By default, C# executables have internal manifests, which means that your
whatever.exe.manifest
file will be ignored.If you go to the properties page for your C# EXE, you'll see there's an "Icon and manifest" section on the "Application tab". Set "Manifest" to the name of your manifest file, and it'll be embedded instead of the default one.
If that doesn't work, you might have to do some post-build steps with MT.EXE in order to merge your external manifest with the default internal one and to put the merged manifest back into the .EXE file.
错误代码意味着 Visual Studio 认为某个对象应该实现某个接口,但是当我尝试“连接”到该接口时,该对象响应说它不知道它。
我猜问题出在 SC_COM.dll 中。 TLBIMP.EXE 从 DLL 中存储的元数据中提取类和接口信息,并为该类构建包装器。
例如,如果 SC_COM 是用 C++ 编写的,如果 DLL 的创建者在 IDL 文件中指示某个类实现了该接口,但实际代码不支持该接口,则可能会发生这种情况。
这是该 DLL 可能存在的另一个常见问题来源:有时您有一个实现 ISomething2 接口的类,该接口派生自 ISomething 接口,但该类实现仅识别 ISomething2。 如果实现派生接口,则还必须识别其基接口。 这是一个常见的错误。
您拥有(并控制)DLL 的源代码吗?
the error code means that Visual Studio thinks that a certain object is supposed to implement a certain interface, but when I tries to "connect" to that interface the object responds that it doesn't know about it.
I would guess that the problem is in SC_COM.dll. TLBIMP.EXE extracts class and interface information from metadata stored within the DLL and builds wrappers for the class.
For example, if SC_COM is written in C++, this could happen if the creator of the DLL indicated in the IDL file that a class implements that interface, but the actual code doesn't support that interface.
Here's another common source of problems this DLL might have: sometimes you have a class implementing an ISomething2 interface which derives from an ISomething interface, but the class implementation to only recognize ISomething2. If you implement a derived interface, you must recognize its base interface as well. This is a common mistake.
Do you have (and control) the source code for the DLL?