CLSIDFromProgID 返回错误的 prog id

Posted

技术标签:

【中文标题】CLSIDFromProgID 返回错误的 prog id【英文标题】:CLSIDFromProgID returns wrong prog id 【发布时间】:2021-10-25 22:38:27 【问题描述】:

我们有一个 .NET DLL,其中包含合作伙伴公司可以使用的多个 COM 类和对象。我们目前使用regasm 在注册表中注册COM 类。这已经工作了多年。

我们现在想摆脱 COM 注册并使用side by side assemblies。我目前正在尝试进行这种过渡,但我似乎在终点线上失败了。我们提供了一个使用我们的 COM 类的 C++ 示例应用程序,我尝试让它在没有 COM 注册的情况下运行。

.NET DLL

在我们的 .NET DLL 中,我有一个这样的类:

namespace MyNamespace

    [ComVisible(true)]
    [Guid("ef828ade-b459-4446-80db-956715588601")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("MyVendor.MyClass")]
    public partial class MyClass
    
    

应用程序组装

应与该 COM 类一起使用的 C++ 示例应用程序具有如下清单:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32"
                        name="Microsoft.Windows.Common-Controls"
                        version="6.0.0.0"
                        processorArchitecture="x86" 
                        publicKeyToken="6595b64144ccf1df" 
                        language="*" />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32"
                        name="MyComDll.X"
                        version="1.0.0.0" />
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker"
                                 uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
</assembly>

DLL 程序集

而且 .NET DLL 本身有一个清单来将 COM 类暴露给外界:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32"
                    name="MyComDll.X"
                    version="1.0.0.0" />
  <file name="MyComDll.dll">
    <comClass description="MyVendor.MyClass"
              clsid="ef828ade-b459-4446-80db-956715588601"
              progid="MyVendor.MyClass.1"
              threadingModel="Both">
      <progid>MyVendor.MyClass</progid>
    </comClass>
  </file>
</assembly>

使用 COM

我显然在上面的代码示例中使用了代理名称,但我确保原始代码中的所有名称都是有效的。

在我们的示例 C++ 代码中,我们以这种方式获取 CLSID 并创建类的实例:

HRESULT hr = CLSIDFromProgID(OLESTR("MyVendor.MyClass"), &clsid);

hr = CoCreateInstance(clsid, nullptr, CLSCTX_SERVER, IID_IDispatch, (void**)(&_pMyClass));

出了什么问题

我使用一些调试输出来检查从CLSIDFromProgID() 返回的 GUID 并检查返回值。如果 COM 类是使用regasm 注册的,则返回值为S_OKclsid 与我在 .NET DLL 中为该类指定的 GUID 相同。

但是,如果我删除 COM 注册并使用带有清单的并行程序集,如上所示,我也会得到 S_OK 返回值,但 GUID 完全不同,因此我无法创建这节课。我在任何地方都没有找到从 CLSIDFromProgID() 获得的 GUID - 无论是在注册表中还是在我的开发解决方案中。

你知道我做错了什么吗?

我知道我的 C++ 示例应用程序通常可以很好地处理我们的 COM 对象,因为如果注册了 COM 类,它就可以完美运行。 我检查了我使用 Microsoft's specification 和各种指南创建的清单的每个部分。 我在 Windows 事件日志中没有收到任何 SideBySide 错误,因此我知道清单格式正确。 我确实从 CLSIDFromProgID() 得到了一个 S_OK,所以我知道找到了 ProgID - 它只是提供了错误的 CLSID。 我使用函数StringFromCLSID() 来比较由`CLSIDFromProgID() 找到的CLSID。

【问题讨论】:

在调用CLSIDFromProgID()时使用MyVendor.MyClass.1而不是MyVendor.MyClass是否也有同样的问题?或者如果您将清单中的progid 设置为MyVendor.MyClass 而不是MyVendor.MyClass.1 您的“COM”组件实际上是一个 .NET 程序集,对吗?您使用 comClass 而不是 clrClass 是否有原因?要通过清单向 COM 公开 .NET 程序集,我认为您应该改用 clrClass ??? Using .Net (CLR Managed) Classes in Win32 Applications | Using CLR managed classes in unmanaged win32 applications 使用 sysinternals 中的 Procmon,按注册表访问和您的 .exe 进行过滤,您应该会看到该 guid 的来源。 @Endgegner85 你看到这篇解释现象的文章了吗:manifestmaker.com/sxs/help/confclsid.htm 【参考方案1】:

首先,我要感谢 Joseph Willcoxson 和 Remy Lebeau 将我推向正确的方向!

我的清单中有几个小问题,我可以一个接一个地解决。我犯的一个大错误是假设我从 CLSIDFromProgID 获得的 CLSID 与我在 .NET COM 类中指定的 CLSID 相同。在指出不一定如此之后,我没有再浪费时间,并检查了调用 CoCreateInstance 失败的原因。它通过多次在线研究和测试来找出我犯的错误。

正如 Joseph 所指出的,我应该使用 clrClass 而不是 comClass。我在配置 clrClass 时犯了错误。例如,我为“name”使用了与“progId”相同的名称,但 clrClass 中的“name”是完整的命名空间 + 类名。

【讨论】:

以上是关于CLSIDFromProgID 返回错误的 prog id的主要内容,如果未能解决你的问题,请参考以下文章

iPad Pro 报告错误的屏幕比例

013-ant design pro advanced 错误处理

当我尝试在 sequel pro 中运行此查询时出现错误 [重复]

Ionic pro 构建失败并出现错误 Xcode 9 未提供配置文件

在 Ida Pro 中查找字符串数据引用的引用

IISExpress 从远程机器返回 503 错误