【问题标题】:COM object accessing problem in C#C#中的COM对象访问问题
【发布时间】:2011-06-07 23:42:19
【问题描述】:

我很难弄清楚我做错了什么,所以我想我会在 SO 上问这个问题。我正在尝试自动化测量任务(Qualcomm QXDM),因此想访问测量工具公开的 COM 接口。我编写了以下python代码,效果很好:

from comtypes.client import CreateObject  
QXDM = CreateObject("QXDM.Application")
IQXDM2 = QXDM.GetIQXDM2
...

现在,由于我有一些特定的要求,我正在尝试重写这是 C#。这是我尝试过的:

using QXDM;
QXDM2Class IQXDM = new QXDM2Class();

但是当我尝试运行它时,我得到:

Retrieving the COM class factory for component with CLSID {6777AAE0-D9D2-4EA7-996B-0EECC68F97D8} failed due to the following error: 80040154.

我做错了什么?我可以在Visual Studio的对象浏览器中看到QXDM提供的所有方法和接口。

编辑:似乎后期绑定是汉斯建议的唯一方法。我将代码修改为:

Type QXDM = Type.GetTypeFromProgID("QXDM.Application");
Object QXDMObject = Activator.CreateInstance(QXDM);

这行得通。唯一的麻烦是我需要知道 QXDM 公开了哪些方法和类,我想我可以使用对象浏览器弄清楚。谢谢大家!

【问题讨论】:

    标签: c# com


    【解决方案1】:

    您的代码不一样。在 Python 代码中,您显然使用的是常见的“应用程序”对象。在许多自动化对象模型中,这是您从中创建其他对象的对象。类似于 GetIQXDM2() 方法中的 IQXDM2。

    您的 C# 代码似乎正在尝试创建直接实现 IQXDM2 的类。不能工作,你必须通过应用程序界面。就像错误消息说的那样,该对象没有“类工厂”,应用程序接口创建它。不管它叫什么,它的名字几乎总是有“应用程序”。在互操作引用上使用对象浏览器进行查看。寻找具有 GetIQXDM2 方法的那个。

    如果您没有看到任何类似的东西,那么您可能添加了错误的 DLL。在注册表中查找正确的名称。启动 Regedit.exe 并查看 HKCR\QXDM.Application。您将找到一个带有 guid 的 CLSID 密钥。然后查看HKCR\Clsid\{guid},其中 {guid} 是您找到的 guid。 InprocServer32 项具有 DLL 名称。进程外服务器使用 LocalServer32 键。

    如果这没有成功,那么 COM 服务器可能只供脚本语言使用。非常不寻常,但它可能会发生。在这种情况下,您必须在 C# 代码中使用后期绑定。只有使用 C# 4.0 dynamic 关键字或 VB.NET

    才能轻松做到这一点

    【讨论】:

    • 汉斯,感谢您的回复。在对象浏览器中,我只能看到以下内容:Interop.QXDM -> QXDM -> QXDM2Class。没有 GetQXDM2。
    • 汉斯,感谢一百万的提示。我浏览了注册表。 LocalServer32只有一个名为default的条目,它是“C:\PROGRA~1\Qualcomm\QXDM\Bin\QXDM.exe”。
    【解决方案2】:

    这可能是 DLL 依赖于其他 DLL 的事实。使用 ProcExp (http://www.sysinternals.com/) 进行调试可能会有所帮助

    【讨论】:

    • StefanE,感谢您的回复,我会尝试 ProcExp。但是如果存在依赖问题,Python代码不会也失败吗?
    【解决方案3】:

    我认为 COM 对象已注册正常,否则您的 Python 代码将失败,您将无法在机器上看到它们。如果是这种情况,您的问题是从 C# 访问 COM 对象。尝试指定的方法here

    如果库已经注册, 您可以执行以下步骤来 让 Visual Studio 生成互操作 为你组装

    【讨论】:

    • 史蒂夫,感谢您的回复。我会尝试您指出的方法,并尽快更新结果。
    • 我添加参考的方式是使用您提到的帖子中解释的步骤。 Intellisense 确实给了我类和方法。
    【解决方案4】:

    HRESULT 0x80040154 表示 COM 类未注册。尝试在 COM dll 上运行 regsvr32

    【讨论】:

    • 它找到了 guid,所以它在 HKEY_CLASSES_ROOT 中。可能是版本问题,也可能是平台目标问题。
    • 正如 SRM 所说,我可以在注册表中看到错误中提到的 CLSID。
    • @SRM:本例中的 GUID 来自在类型库上运行 Tlbimp 生成的代码。这指定了 GUID,并且生成的 .Net 类使用 GUID 作为属性进行修饰。
    • 这取决于他如何引用 COM dll。如果他使用 COM 选项卡从“添加引用”中引用它,那么 VS 将“隐藏”创建 RCW。这实际上可能是OP的问题。也许该 dll 注册了多个版本,而他抓错了?这只是猜测,因为它找不到 dll 入口点(因此是 80040154 错误代码)。
    • SRM,我在 VS 中使用了“添加引用”并单击 COM 选项卡并选择了这个特定对象。
    【解决方案5】:

    可能是您正在构建 64 位。检查您的平台目标。确保它是 32 位的。

    【讨论】:

    • SRM,感谢您的回复。我正在开发 32 位版本的 Windows。
    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    相关资源
    最近更新 更多