Загрузка 32-битной или 64-битной COM-библиотеки бок о бок в зависимости от разрядности, с которой работает приложение - PullRequest
3 голосов
/ 23 июля 2010

У меня есть приложение .NET, которое использует COM DLL, 32-битная и 64-битная версии. Я написал два манифеста приложения, которые обеспечивают совместное взаимодействие COM на 32-битной или 64-битной версии. Вот 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 Ответ

1 голос
/ 28 июля 2010

Я не нашел способа сделать это с помощью манифеста приложения. Поэтому я отбросил манифест приложения в пользу программного решения, использующего 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...