Ориентация как 32-битной, так и 64-битной с Visual Studio в том же решении/проекте

У меня есть небольшая дилемма о том, как настроить мои визуальные студийные сборки для мультитаргетинга.

Фон: С#.NET v2.0 с p/invoking в сторонние 32-разрядные библиотеки DLL, SQL compact v3.5 SP1, с проектом установки. Сейчас целевая платформа установлена ​​на x86, поэтому ее можно запустить в Windows x64.

Сторонняя компания только что выпустила 64-битные версии своей DLL, и я хочу создать выделенную 64-битную программу.

Возникает ряд вопросов, на которые у меня пока нет ответов. Я хочу иметь ту же самую базу кода. Я должен строить со ссылками на 32-битный набор DLL или 64-битных DLL. (Как сторонний, так и SQL Server Compact)

Можно ли это решить с помощью двух новых наборов конфигураций (Debug64 и Release64)?

Должен ли я создать 2 отдельных проекта установки (проекты стандартной визуальной студии, без Wix или любой другой утилиты), или это можно решить в пределах того же .msi?

Любые идеи и/или рекомендации будут приветствоваться.

Ответ 1

Да, вы можете ориентировать как x86, так и x64 с той же базой кода в том же проекте. В общем, все будет просто работать, если вы создадите правильные конфигурации решений в VS.NET(хотя P/Invoke для полностью неуправляемых DLL, скорее всего, потребует некоторый условный код): элементы, которые, как мне показалось, требуют особого внимания, следующие:

  • Ссылки на внешние управляемые сборки с тем же именем, но с их собственной специфической битностью (это также относится к сборкам COM-соединений)
  • Пакет MSI (который, как уже отмечалось, должен будет ориентироваться на x86 или x64)
  • Любые пользовательские действия .NET Installer, основанные на классе, в вашем пакете 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 диалоговое окно Assembly Reference немного смущается этими изменениями, и вы можете столкнуться с некоторыми предупреждениями о сборках с неправильным целевым процессором, но все ваши сборки будут работать нормально.

Решение проблемы MSI происходит следующим образом, и, к сожалению, для этого будет нужен инструмент nonVS.NET: я предпочитаю Caphyon Advanced Installer для этой цели, поскольку он отвлекает основной трюк (создайте общий MSI, а также 32-разрядные и 64-разрядные MSI файлы и используйте средство установки .EXE, чтобы извлечь нужную версию и сделать требуемые исправления во время выполнения) очень, очень хорошо.

Вероятно, вы можете достичь тех же результатов, используя другие инструменты или набор инструментов Windows Installer XML (WiX), но Advanced Installer делает все так просто ( и довольно доступным в этом), что я никогда не смотрел альтернативы.

Одна вещь, которую вы может по-прежнему нуждаться в WiX, хотя, даже при использовании Advanced Installer, предназначена для ваших пользовательских действий .NET Installer Class. Хотя тривиально указать определенные действия, которые должны выполняться только на определенных платформах (с использованием условий выполнения VersionNT64 и NOT VersionNT64, соответственно), встроенные пользовательские действия AI будут выполняться с использованием 32-разрядной Framework даже на 64-битных машинах.

Это может быть исправлено в будущей версии, но на данный момент (или при использовании другого инструмента для создания ваших MSI, имеющих такую ​​же проблему), вы можете использовать поддержку настраиваемых действий с поддержкой WiX 3.0 для создания функциональных DLL с надлежащей битовой который будет выполнен с использованием соответствующей Framework.


Изменить: начиная с версии 8.1.2, Advanced Installer корректно поддерживает 64-битные пользовательские действия. Начиная с моего первоначального ответа, его цена немного выросла, к сожалению, несмотря на то, что она по-прежнему чрезвычайно хороша по сравнению с InstallShield и ее ilk...


Изменить: если ваши 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>

Условие также сводится к всем типам сборки, выпуску или отладке и просто указывает архитектуру процессора.

Ответ 2

Скажем, у вас есть библиотеки DLL для обеих платформ, и они находятся в следующем местоположении:

C:\whatever\x86\whatever.dll
C:\whatever\x64\whatever.dll

Вам просто нужно отредактировать файл .csproj:

<HintPath>C:\whatever\x86\whatever.dll</HintPath>

Для этого:

<HintPath>C:\whatever\$(Platform)\whatever.dll</HintPath>

Затем вы сможете создать свой проект, ориентированный на обе платформы, и MSBuild будет выглядеть в правильном каталоге для выбранной платформы.

Ответ 3

Не уверен в общем ответе на ваш вопрос, но подумал, что я хотел бы указать комментарий в разделе "Дополнительная информация" страницы SQL Compact 3.5 SP1 видя, что вы смотрите на x64 - надеюсь, что это поможет.

Из-за изменений в SQL Server Compact SP1 и дополнительная 64-разрядная версия поддержка, централизованно установленная и смешанная режиме 32-битной версии SQL Server Compact 3.5 и 64-разрядные версия SQL Server Compact 3.5 SP1 может создать то, что кажется периодические проблемы. Чтобы свести к минимуму потенциала для конфликтов и нейтральное развертывание платформы клиентских приложений, централизованно установка 64-разрядной версии SQL Server Compact 3.5 SP1 с использованием Файл установщика Windows (MSI) также требует установки 32-разрядной версии SQL Server Compact 3.5 SP1 MSI файл. Только для приложений требуют собственных 64-битных, частных развертывание 64-разрядной версии SQL Server Compact 3.5 SP1 может быть используется.

Я прочитал это как "включить 32-битные файлы SQLCE , а также 64-битные файлы", если они распространяются для 64-битных клиентов.

Делает жизнь интересной, я думаю.. должен сказать, что мне нравится "то, что кажется прерывистыми проблемами"... звучит немного как "вы воображаете вещи, но на всякий случай, сделайте это..."

Ответ 4

Относительно вашего последнего вопроса. Скорее всего, вы не можете решить это в одном MSI. Если вы используете реестр/системные папки или что-то подобное, сам MSI должен знать об этом, и вы должны подготовить 64-битный MSI для правильной установки на 32-битную машину.

Существует вероятность того, что вы можете установить продукт как 32-разрядное приложение и по-прежнему иметь возможность запускать его как 64-битный, но я думаю, что это может быть несколько сложно достичь.

что, как я сказал, я думаю, что вы должны иметь возможность сохранить единую базу кода для всего. На моем нынешнем рабочем месте нам это удалось. (но это потребовало некоторого жонглирования, чтобы все играло вместе)

Надеюсь, это поможет. Heres ссылка на некоторую информацию, связанную с 32/64 бит проблемами: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html

Ответ 5

Если вы используете пользовательские действия, написанные в .NET, как часть вашего установщика MSI, у вас возникает другая проблема.

"Прокладка", которая запускает эти пользовательские действия, всегда 32 бит, тогда ваше пользовательское действие также будет работать на 32 бит, несмотря на то, что вы указываете.

Дополнительная информация и некоторые ниндзя перемещаются, чтобы обойти (в основном изменить MSI, чтобы использовать 64-битную версию этой прокладки)

Создание MSI в Visual Studio 2005/2008 для работы с SharePoint 64

64-разрядные управляемые пользовательские действия с Visual Studio

Ответ 6

Вы можете сгенерировать два решения по-другому и объединить их позже! Я сделал это для VS 2010. и он работает. У меня было два разных решения, созданных CMake, и я объединил их

Ответ 7

Вы можете использовать условие для ItemGroup для ссылок dll в файле проекта.
Это заставит визуальную студию перепроверять состояние и ссылки всякий раз, когда вы меняете активную конфигурацию.
Просто добавьте условие для каждой конфигурации.

Пример:

 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <Reference Include="DLLName">
      <HintPath>..\DLLName.dll</HintPath>
    </Reference>
    <ProjectReference Include="..\MyOtherProject.vcxproj">
      <Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project>
      <Name>MyOtherProject</Name>
    </ProjectReference>
  </ItemGroup>