У меня небольшая дилемма относительно того, как настроить мои сборки визуальной студии для множественного таргетинга.
Предыстория: c # .NET v2.0 с вызовом p / в сторонние 32-битные библиотеки DLL, SQL compact v3.5 SP1 с проектом установки. Прямо сейчас целевая платформа установлена на x86, поэтому ее можно запускать в Windows x64.
Сторонняя компания только что выпустила 64-битные версии своих DLL, и я хочу создать специальную 64-битную программу.
Это поднимает некоторые вопросы, на которые у меня еще нет ответов. Я хочу иметь точно такую же базу кода. Я должен строить со ссылками на 32-битный набор DLL или 64-битный DLL. (И сторонние производители, и SQL Server Compact)
Можно ли решить эту проблему с помощью двух новых наборов конфигураций (Debug64 и Release64)?
Должен ли я создать 2 отдельных проекта установки (стандартные проекты Visual Studio, без Wix или какой-либо другой утилиты), или это можно решить в одном и том же .msi?
Любые идеи и / или рекомендации приветствуются.
источник
Ответы:
Да, вы можете настроить таргетинг на x86 и x64 с одной и той же базой кода в одном проекте. В общем, все будет просто работать, если вы создадите правильные конфигурации решения в VS.NET (хотя P / Invoke для полностью неуправляемых библиотек DLL, скорее всего, потребует некоторого условного кода): элементы, которые, как я обнаружил, требуют особого внимания:
Проблема ссылки на сборку не может быть решена полностью в VS.NET, так как это позволит вам только один раз добавить ссылку с заданным именем в проект. Чтобы обойти это, отредактируйте файл проекта вручную (в VS щелкните правой кнопкой мыши файл проекта в обозревателе решений, выберите «Выгрузить проект», затем снова щелкните правой кнопкой мыши и выберите «Изменить»). После добавления ссылки, скажем, на версию сборки x86, ваш файл проекта будет содержать что-то вроде:
Оберните этот тег Reference внутри тега ItemGroup, указав конфигурацию решения, к которой он применяется, например:
Затем скопируйте и вставьте весь тег ItemGroup и отредактируйте его, чтобы он содержал сведения о вашей 64-битной DLL, например:
После перезагрузки вашего проекта в 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):
Условие также сокращено до всех типов сборки, выпуска или отладки и просто определяет архитектуру процессора.
источник
Допустим, у вас есть сборки DLL для обеих платформ, и они находятся в следующем месте:
Вам просто нужно отредактировать файл .csproj из этого:
К этому:
После этого вы сможете создать свой проект, ориентированный на обе платформы, и MSBuild будет искать в правильном каталоге для выбранной платформы.
источник
Не уверен в полном ответе на ваш вопрос, но подумал, что хотел бы указать на комментарий в разделе «Дополнительная информация» на странице загрузки SQL Compact 3.5 SP1, видя, что вы смотрите на x64 - надеюсь, это поможет.
Я прочитал это как «включить 32-битные файлы SQLCE, а также 64- битные файлы» при распространении для 64-битных клиентов.
Делает жизнь интересной, я думаю ... должен сказать, что мне нравится фраза "что-то вроде прерывистых проблем" ... звучит немного как "вы что-то воображаете, но на всякий случай сделайте это ..."
источник
Одна сборка .Net с зависимостями x86 / x64
В то время как все остальные ответы дают вам решение для создания разных сборок в соответствии с платформой, я даю вам возможность иметь только конфигурацию «AnyCPU» и создать сборку, которая работает с вашими dll x86 и x64.
Для этого вам нужно написать код для сантехники.
Разрешение правильных x86 / x64-dll во время выполнения
шаги:
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
Добавьте этот сценарий postbuild в свой запускаемый проект, используйте и измените пути этого сценария sp, чтобы он копировал все ваши x86 / x64 dll в соответствующие подпапки вашего сборочного bin \ x86 \ bin \ x64 \
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64
-> Когда вы запустите приложение сейчас, вы получите исключение, что сборка не может быть найдена.
Зарегистрируйте событие AssemblyResolve в самом начале точки входа в ваше приложение.
этим методом:
Преимущества:
Недостатки: - Отсутствие ошибок во время компиляции, когда dll x86 / x64 не совпадают. - Вы все равно должны запустить тест в обоих режимах!
При необходимости создайте второй исполняемый файл, который является эксклюзивным для архитектуры x64, с помощью Corflags.exe в сценарии postbuild.
Другие варианты, которые стоит попробовать: - Вам не нужен обработчик событий AssemblyResolve, если вы гарантируете, что правильные библиотеки DLL копируются в вашу двоичную папку при запуске (Оценить архитектуру процесса -> переместить соответствующие библиотеки DLL из x64 / x86 в папку bin и обратно. ) - В установщике оцените архитектуру и удалите двоичные файлы для неправильной архитектуры и переместите правильные в папку bin.
источник
По поводу вашего последнего вопроса. Скорее всего, вы не сможете решить эту проблему с помощью одного MSI. Если вы используете реестр / системные папки или что-то подобное, сам MSI должен знать об этом, и вы должны подготовить 64-битный MSI для правильной установки на 32-битном компьютере.
Существует вероятность того, что вы можете установить свой продукт как 32-битное приложение и по-прежнему иметь возможность запускать его как 64-битное, но я думаю, что это может быть довольно сложно достичь.
При этом я думаю, что у вас должна быть возможность сохранить единую базу кода для всего. На моем нынешнем рабочем месте нам это удалось. (но потребовалось некоторое жонглирование, чтобы заставить все играть вместе)
Надеюсь это поможет. Вот ссылка на некоторую информацию, связанную с проблемами 32/64 бит: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html
источник
Если вы используете настраиваемые действия, написанные на .NET, как часть установщика MSI, у вас возникает другая проблема.
Прокладка, которая запускает эти настраиваемые действия, всегда 32-разрядная, тогда ваше настраиваемое действие также будет работать 32-разрядным, независимо от того, какую цель вы укажете.
Дополнительная информация и некоторые приемы ниндзя, чтобы обойти (в основном измените MSI, чтобы использовать 64-битную версию этой прокладки)
Создание MSI в Visual Studio 2005/2008 для работы на SharePoint 64
64-битные управляемые настраиваемые действия с Visual Studio
источник
Вы можете сгенерировать два решения по-разному и потом объединить их! Я сделал это для VS 2010. и это работает. У меня было 2 разных решения, созданных CMake, и я их объединил
источник
Вы можете использовать условие для ItemGroup для ссылок на dll в файле проекта.
Это заставит Visual Studio повторно проверять условие и ссылки всякий раз, когда вы меняете активную конфигурацию.
Просто добавьте условие для каждой конфигурации.
Пример:
источник