根据应用程序运行的位数加载32位或64位并行COM DLL

时间:2010-07-23 11:41:42

标签: com-interop manifest side-by-side

我有一个使用COM DLL的.NET应用程序,其中包含32位和64位版本。我写了两个应用程序清单,它们在32位或64位上进行并行COM互操作。这是32位版本:

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity name="MyApp" version="1.0.0.0" type="win32" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity 
           type="win32" 
           name="MyCOMDll_32.dll" 
           version="1.2.3.4" 
           processorArchitecture="x86" 
           publicKeyToken="0000000000000000"
           language="*" />
    </dependentAssembly>
  </dependency>
</assembly>

但是,保留两个清单会导致可移植性丢失:您需要确定安装应用程序时要使用的版本。并且64位应用程序无法再以32位模式运行。

是否有可能让.NET应用程序加载正确的32位或64位DLL,具体取决于它运行的位数? 我尝试使用两个依赖项元素,一个使用<assemblyIdentity processorArchitecture="x86" .../>,另一个使用<assemblyIdentity processorArchitecture="amd64" .../>,但这会导致应用程序配置错误。

我非常感谢答案。 问候, Moritz的

1 个答案:

答案 0 :(得分:1)

我还没有找到使用应用程序清单执行此操作的方法。因此,我使用Activation上下文API删除了应用程序清单,以支持程序化解决方案。 此解决方案已从http://support.microsoft.com/kb/830033/en-us改编(其中字段cookie必须是IntPtr而不是uint)。 我已经用

替换了EnsureActivationContextCreated()方法的内部部分

if (!contextCreationSucceeded)
{
    string manifestLoc = Environment.Is64BitProcess
    ? "MyCOMDll_64.dll.manifest"
    : "MyCOMDll_32.dll.manifest";

    myComActivationContext = new NativeMethods.ACTCTX();
    myComActivationContext.cbSize = Marshal.SizeOf(typeof(NativeMethods.ACTCTX));
    myComActivationContext.lpSource = manifestLoc;

    // Note this will fail gracefully if file specified
    // by manifestLoc doesn't exist.
    hActCtx = NativeMethods.CreateActCtx(ref myComActivationContext);
    contextCreationSucceeded = hActCtx != Failed;
}