Как развернуть 64-разрядную версию DLL в Azure, но использовать 32-разрядную версию на устройствах разработчика
Мы с моим деловым партнером совместно разрабатываем веб-приложение, развернутое в Azure. Моя коробка основана на 64-битной Windows 7, но мой партнер использует 32-битную Windows 7.
Из среды IDE VS2010, когда я добавил ссылку на файл ieframe.dll из моего каталога System32 (64-разрядная версия на моем компьютере), среда IDE фактически представила 32-разрядную версию DLL для SysWoW64.
Оба dev-бокса отлично работают с 32-битной WOW-версией ieframe.dll, но при развертывании в Azure мы получаем исключение EntryPointNotFoundException при вызове Interop/DllImport в ieeframe.dll. Похоже, что Azure хочет иметь 64-битную версию.
Как мы можем развернуть 64-разрядную версию в Azure, но продолжать использовать 32-разрядную версию на наших устройствах разработки?
РЕДАКТИРОВАТЬ: Очевидно, что мы можем сделать это вручную, скопировав куда-нибудь 64-разрядный файл ieframe.dll, а затем вручную поместив его в каталог bin, но есть ли лучший способ сделать это в Azure?
РЕДАКТИРОВАНИЕ № 2: Для этого сценария мы в конечном итоге изменили узел для Azure с osFamily="1" на osFamily="2". При этом устанавливается Windows Server 2008 R2, который включает IE8 (а не IE7 в Windows Server 2008 SP1). Нет необходимости связываться с 32-битной или 64-битной версиями или вручную копировать библиотеки DLL на сервер.
1 ответ
Если вы всегда развертываете в Azure с 64-разрядной машины, вы можете изменить файл проекта, чтобы скопировать правильную DLL в папку bin во время сборки, в зависимости от типа процессора машины, выполняющей сборку. Это прекрасно работает для нас, потому что мы развертываем в Azure с 64-битного сервера сборки. Если это звучит как хорошее решение, выполните следующие действия:
1 - Создайте внешнюю папку lib, которая содержит две подпапки с именами 32 и 64.
2 - Поместите 32-разрядную версию DLL в папку 32, а 64-разрядную версию в папку 64.
3 - Откройте поврежденный файл проекта в текстовом редакторе.
4 - Добавьте следующий узел в файл проекта сразу после ItemGroup, которая содержит элементы "reference include". Это скопирует правильную DLL на основе системных переменных среды:
<ItemGroup>
<DllToCopy Condition=" '$(PROCESSOR_ARCHITECTURE)' == 'x86' And '$(PROCESSOR_ARCHITEW6432)' == '' " Include="..\ext-lib\32\mydll.dll" />
<DllToCopy Condition=" '$(PROCESSOR_ARCHITECTURE)' == 'AMD64' Or '$(PROCESSOR_ARCHITEW6432)' == 'AMD64' " Include="..\ext-lib\64\mydll.dll" />
</ItemGroup>
5 - Наконец, измените цель проекта BeforeBuild следующим образом:
<Target Name="BeforeBuild">
<Copy SourceFiles="@(DllToCopy)" DestinationFolder="$(OutputPath)" />
</Target>
Другой вариант - скопировать правильную DLL в папку bin на основе конфигурации сборки (менее идеальной). Например, если бы у вас была конфигурация сборки с именем Production, вы бы выполнили шаги, описанные выше, за исключением того, что шаг 4 будет содержать это:
<ItemGroup>
<DllToCopy Condition=" '$(Configuration)' != 'Production' " Include="..\ext-lib\32\mydll.dll" />
<DllToCopy Condition=" '$(Configuration)' == 'Production' Include="..\ext-lib\64\mydll.dll" />
</ItemGroup>
Еще один (и даже менее идеальный) вариант - скопировать 64-разрядную версию DLL в папку bin с помощью задачи запуска Azure.
Надеюсь это поможет.