Да, вы можете настроить таргетинг на x86 и x64 с одной и той же базой кода в одном проекте. В общем, все будет просто работать, если вы создадите правильные конфигурации решения в VS.NET (хотя P / Invoke для полностью неуправляемых библиотек DLL, скорее всего, потребует некоторого условного кода): элементы, которые, как я обнаружил, требуют особого внимания:
- Ссылки на внешние управляемые сборки с тем же именем, но с их собственной конкретной разрядностью (это также относится к сборкам взаимодействия с COM)
- Пакет MSI (который, как уже отмечалось, должен быть ориентирован на x86 или x64)
- Любые настраиваемые действия на основе классов установщика .NET в вашем пакете MSI
Проблема ссылки на сборку не может быть решена полностью в VS.NET, так как это позволит вам только один раз добавить ссылку с заданным именем в проект. Чтобы обойти это, отредактируйте файл проекта вручную (в VS щелкните правой кнопкой мыши файл проекта в обозревателе решений, выберите «Выгрузить проект», затем снова щелкните правой кнопкой мыши и выберите «Изменить»). После добавления ссылки, скажем, на версию сборки x86, ваш файл проекта будет содержать что-то вроде:
<Reference Include="Filename, ..., processorArchitecture=x86">
<HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>
Оберните этот тег Reference внутри тега ItemGroup, указав конфигурацию решения, к которой он применяется, например:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<Reference ...>....</Reference>
</ItemGroup>
Затем скопируйте и вставьте весь тег ItemGroup и отредактируйте его, чтобы он содержал сведения о вашей 64-битной DLL, например:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<Reference Include="Filename, ..., processorArchitecture=AMD64">
<HintPath>C:\path\to\x64\DLL</HintPath>
</Reference>
</ItemGroup>
После перезагрузки вашего проекта в VS.NET диалоговое окно «Справочник по сборке» будет немного сбито с толку этими изменениями, и вы можете столкнуться с некоторыми предупреждениями о сборках с неправильным целевым процессором, но все ваши сборки будут работать нормально.
Следующим шагом будет решение проблемы с MSI, и, к сожалению, для этого потребуется инструмент, отличный от VS.NET: для этой цели я предпочитаю Advanced Installer от Caphyon , так как он реализует основной трюк (создайте общий MSI, а также 32-разрядный и 64-разрядные MSI, а также использовать средство запуска установки .EXE для извлечения нужной версии и выполнения необходимых исправлений во время выполнения) очень и очень хорошо.
Вероятно, вы можете добиться тех же результатов с помощью других инструментов или набора инструментов Windows Installer XML (WiX) , но Advanced Installer упрощает работу (и при этом вполне доступен), что я никогда особо не рассматривал альтернативы.
Одна вещь, для которой вам может потребоваться WiX, даже при использовании Advanced Installer, - это настраиваемые действия вашего .NET Installer Class. Хотя тривиально указать определенные действия, которые должны выполняться только на определенных платформах (с использованием условий выполнения VersionNT64 и НЕ VersionNT64 соответственно), встроенные настраиваемые действия AI будут выполняться с использованием 32-разрядной платформы, даже на 64-разрядных машинах. .
Это может быть исправлено в будущем выпуске, но на данный момент (или при использовании другого инструмента для создания ваших MSI-файлов с той же проблемой) вы можете использовать поддержку управляемых настраиваемых действий WiX 3.0 для создания DLL действий с надлежащей разрядностью, которая будет выполняться с использованием соответствующего Framework.
Изменить: начиная с версии 8.1.2 Advanced Installer правильно поддерживает 64-разрядные пользовательские действия. С момента моего первоначального ответа его цена, к сожалению, немного выросла, хотя он по-прежнему чрезвычайно выгоден по сравнению с InstallShield и ему подобными ...
Изменить: если ваши библиотеки DLL зарегистрированы в GAC, вы также можете использовать стандартные теги ссылок таким образом (например, SQLite):
<ItemGroup Condition="'$(Platform)' == 'x86'">
<Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x64'">
<Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</ItemGroup>
Условие также сокращено до всех типов сборки, выпуска или отладки и просто определяет архитектуру процессора.