views:

16

answers:

1

Hi, I have a .NET application that uses a COM DLL, of which there is both a 32bit and a 64bit version. I have written two application manifests that make side-by-side COM interop work on either 32 Bit or 64 Bit. Here the 32-bit version:

<?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>

However, maintaining two manifests leads to the loss of portability: you need to decide which version to use when you install the application. And the 64-bit application can no longer be run in 32-bit mode.

Is there a possibility to get the .NET application to load the correct 32-bit or 64-bit DLL depending on the bitness under which it runs? I have tried using two dependency elements, one with <assemblyIdentity processorArchitecture="x86" .../> and one with <assemblyIdentity processorArchitecture="amd64" .../>, but that results in an application configuration error.

I'd be very grateful for answers. Regards, Moritz

A: 

I have not found a way to do this with an application manifest.Therefore, I dropped the application manifest in favor of a programmatic solution using the Activation context API. This solution has been adapted from http://support.microsoft.com/kb/830033/en-us (where the field cookie must be an IntPtr not a uint). I have replaced the inner part of the EnsureActivationContextCreated() method by


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;
}

related questions