我建立了一个使用两个COM服务器DLL的COM客户端应用程序;我希望这个应用程序在没有COM注册的情况下运行 - 即:Winsxs / .manifests

当我尝试从我的客户端应用程序创建我的COM对象的实例时,我得到(......几乎预期的...)“类没有注册”的消息。

我之前已经成功了,但是我无法弄清楚为什么这个失败。


这里有几个细节:

  • 我所拥有的模块:
    • 一个依赖于2个com服务器(dll1.dll和dll2.dll)的mfc客户端
    • dll1.dll com服务器取决于dll2.dll
    • dll2.dll没有com依赖

      我有com对象:

      • 在dll1.dll(.idl语言)

        -

        [
            object,
            uuid(262D00FB-3B9F-4A76-98FC-3051FDCAF0A6),
            dual,
            nonextensible,
            helpstring("IDialogManager Interface"),
            pointer_default(unique)
        ]
        interface IDialogManager : IDispatch{
        };
        [
                uuid(58562535-BCA5-4D04-BB92-78F90EDA201E),
                //...
        ]
        dispinterface _IDialogManagerEvents
        {
        };
        [
                uuid(D599D3F0-A4D1-44A7-87A9-16032CC613CA),
                //...
        ]
        coclass DialogManager
        {
                [default] interface IDialogManager;
                [default, source] dispinterface _IDialogManagerEvents;
        };
        
        .

        -

        • 在dll2.dll

          -

          [
              object,
              uuid(2A183A2E-A620-4E00-B657-C9D2E59201D4),
              nonextensible,
              helpstring("ICadWizardsManager Interface"),
              pointer_default(unique)
          ]
          interface ICadWizardsManager : IDispatch{
          };
          [
              object,
              uuid(FE97F3FB-8930-43BC-947D-64C90F45A071),
              nonextensible,
              helpstring("ICadWizard Interface"),
              pointer_default(unique)
          ]
          interface ICadWizard : IDispatch{
          };
          [
              uuid(5365D4E6-ADFB-4429-9DEA-C44CC94AA3EF),
          ]
          dispinterface _ICadWizardEvents
          {
          };
          [
              uuid(CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4),
          ]
          coclass CadWizard
          {
              [default] interface ICadWizard;
              [default, source] dispinterface _ICadWizardEvents;
          };
          [
              uuid(3164FAC4-6F5F-4E4D-9B09-DC4115850D78),
          ]
          dispinterface _ICadWizardsManagerEvents
          {
          };
          [
              uuid(707CB6C8-311E-45EC-9DCB-50477F588BAF),
          ]
          coclass CadWizardsManager
          {
              [default] interface ICadWizardsManager;
              [default, source] dispinterface _ICadWizardsManagerEvents;
          };
          
          .

          -

          • 客户端呼叫

            -

            IDialogManagerPtr dialogManager;
            dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered"
            
            .

            -

            • client.exe.2.Manifest

              -

              <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
              <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
              
              <assemblyIdentity name="client" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
              <file name="dll2.dll">
               <comClass
                   clsid="{707CB6C8-311E-45EC-9DCB-50477F588BAF}"
                   threadingModel="apartment">
               </comClass>
               <comClass
                   clsid="{CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4}"
                   threadingModel="apartment">
               </comClass>
              </file>
              
              <file name="dll1.dll">
               <comClass
                   clsid="{D599D3F0-A4D1-44A7-87A9-16032CC613CA}"
                   threadingModel="apartment">
               </comClass>
              </file>
              
              </assembly>
              
              .

              -


              在SXS激活上下文中生成时我没有错误: - Windows日志中没有错误(应该意味着我的清单语法是正确的) - SXStrace没有检测到错误(具有“INFO:激活上下文生成的日志结束。”消息,不包含错误或Sucpicious消息;此外,我看到我的清单已正确加载)

              任何想法?

              有没有办法使用sxstrace调试sxs?获取实际注册的COM或CLR类列表(例如???

              谢谢你提前

有帮助吗?

解决方案

There are usually - at least - two manifests involved when building the activation context for registration free COM.

There is the EXE manifest, that specifies its dependent assemblies, including the assembly containing the COM components, and there is the assembly manifest, describing the dll's, window classes, and COM objects in the assembly.

This Blog contains information about what the .2 means. Basically, when the system looks for a manifest, it looks for modulename.exe[.resid].manifest - In the case that resid is 1, it is omitted.

So, you are using MFC, which means DevStudio, which means that your project should already be configured to produce a RT_MANIFEST resource automatically with the c-runtime and common control 6 settings in it.

Visual Studio 2005 supports this syntax to merge dependentAssembly elements with your applications manifest without having to try and merge XML directly:

#pragma comment(linker, \
    "\"/manifestdependency:type='Win32' "\
    "name='client' "\
    "version='1.0.0.0' "\
    "processorArchitecture='*' "\
    "language='*'\"")

So, if you add that to a cpp or header in your .exe, and then save your client.exe.2.manifest as "client.manifest", you should be all systems go.

其他提示

The simple explanation is that the .manifest file isn't being used. Which is highly likely in this scenario, your .exe almost certainly already contains a manifest, embedded as a resource. Very common for a MFC app to enable visual styles. And for code compiled by the VS2005 or 2008 compilers which embeds a manifest to find the runtime DLLs.

To verify this, use File + Open + File and select the compiled .exe file. Look for the RT_MANIFEST node. If Windows finds such an embedded manifest it isn't going to continue looking for a file-based one. You need to merge your regfree COM entries into the embedded one. I wish I could give you a good MSDN Library link but the docs about manifests suck serious rock.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top