Подтвердить что ты не робот

Есть ли простой способ заставить Visual Studio 2015 использовать определенную утилиту ToolsVersion?

При создании проекта или решения с использованием определенной версии msbuild я могу выбрать более раннюю цепочку инструментов .net с помощью переключателя /toolsversion или /tv:

"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln

Это Just Works для всех версий msbuild, а версия csc.exe и т.д. правильно выбрана на основе вышеперечисленного:

> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:4.0 amazing.sln
...
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe ...
...

> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
...
CoreCompile:
  C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe ...
...

Если я не укажу /tv, то в зависимости от какой версии msbuild, которую я использую, и ряда переменных среды, я могу получить любой из:

  • Инструмент ToolsVersion, указанный в элементе верхнего уровня в файле проекта
  • Инструмент ToolsVersion, соответствующий версии msbuild.exe Я использую
  • Значение из msbuild.exe.config
  • Значение из реестра

(см. различные версии страницы "Параметры переопределения параметров инструмента" в MSDN).

Итак, чтобы иметь сборки, которые имеют согласованные результаты на сервере сборки и на моей локальной машине, я использую /tv при запуске msbuild.exe (на самом деле это принудительно применяется в psake script, который также гарантирует, что он использует соответствующую версию msbuild.exe).

Однако Я не могу использовать переключатель /tv при создании с помощью Visual Studio. Вместо этого Visual Studio 2013 и выше будут использовать инструментальную цепочку .net, поставляемую с этой версией Visual Studio, если:

  • Установлена ​​переменная среды MSBUILDLEGACYDEFAULTTOOLSVERSION и...
  • ... все файлы проекта имеют атрибут ToolsVersion, установленный для версии, которую я хочу использовать.

Это так барокко, что я не могу поверить, что кто-то на самом деле это делает. Мои вопросы таковы:

  • Кто-нибудь делает MSBUILDLEGACYDEFAULTTOOLSVERSION вещь?
  • Если нет, существует ли другой способ заставить Visual Studio использовать конкретную утилиту ToolsVersion, не использующую версию Visual Studio, поставляемую с этой утилитой ToolsVersion? Что-то, что можно было бы сохранить в контроле версий (например, в проекте или в каком-либо другом файле настроек) было бы идеальным.

И наконец:

  • Мне все равно? Учитывая, что каждая последующая версия компилятора С# должна иметь возможность обрабатывать входные данные предыдущих версий, и я могу установить целевую структуру .net и уровень языка С# в файле проекта, достаточно ли этого для обеспечения повторяемости сборки?

(Мое предубеждение в том, что я должен заботиться, поскольку:

  • Я хочу, чтобы сборки в среде IDE и на сервере сборки были одинаковыми (конечно)
  • Я хочу иметь возможность использовать VS2015 (и будущие версии), потому что это лучшая среда IDE, чем предыдущие, но я не хочу быть обязанным использовать новую инструментальную цепочку, пока не решит.

Возможно, я хочу слишком много...)

Для конкретного примера проблемы см. мой репозиторий msbuild-vs-vs2015-toolsversion в github.


Некоторое предположение: я спрашиваю об этом, потому что у нас недавно возникла ошибка построения CI, когда один из моих коллег представил код С# 6.0, который скомпилирован с Roslyn на их копии Visual Studio 2015, но не прошел в CI, потому что использует предыдущий релиз .net toolchain (они использовали автоматическое свойство без сеттера, что прекрасно в Roslyn, но не в более ранних версиях). Мы будем обновлять сборку CI до Roslyn, но я хотел посмотреть, не можем ли мы предотвратить подобное событие в будущем.

4b9b3361

Ответ 1

Я решил это, написав расширение Visual Studio, которое временно устанавливает переменную среды MSBUILDDEFAULTTOOLSVERSION на время сборки; значение, которое будет использоваться, считывается из файла .toolsversion в том же каталоге, что и файл .sln. Psake script считывает один и тот же файл .toolsversion и передает значение в /tv.

Код расширения можно найти здесь: https://github.com/guyboltonking/set-toolsversion-extension. К сожалению, на данный момент я не работаю с С++ или даже с Visual Studio, поэтому я не могу оказать ему никакой поддержки (но могу сказать, что я использовал его без каких-либо проблем в течение нескольких месяцев).

Престижность @efaruk за напоминание о существовании MSBUILDDEFAULTTOOLSVERSION.

Изменить: Благодаря @mbadawi23 теперь можно использовать расширение как с VS2015, так и с VS2017.

Ответ 2

Примечание. Вы всегда можете создать файл msbuild для создания своего проекта, используя его или самостоятельно изменить свой проект, и вы можете условно определить версию своего инструмента (https://msdn.microsoft.com/en-us/library/7z253716.aspx) (.csproj также является структурированным msbuild script с разным расширением, и он также будет совместим с VS).

С уважением...

Edit:

https://msdn.microsoft.com/en-us/library/bb383985.aspx

установив свойство $(ProjectToolsVersion) в проекте в рамках решения. Это позволяет вам создавать проект в решении с версией набора инструментов, которая отличается от версии других проектов.

Итак, я думаю, у вас есть ваш ответ;)

Ответ 3

Чтобы принудительно использовать определенную версию С# в Visual Studio 2015, вы можете войти в свойства проекта → Build → Advanced → Language Version.

Если вы установите значение 5, компилятор будет жаловаться на функции С# 6: Функция "..." недоступна на С# 5. Используйте язык версии 6 или выше.

Alternativly ReSharper также имеет некоторые инструменты для этого.

Ответ 4

То, что вы видите в Visual Studio (инструменты и т.д.) и код, лежащий за ними, не входит в состав скомпилированных данных, они являются просто визуальным/читаемым представлением при компиляции их как более ранней версии VS, которую вы создаете исполняемый из этой версии.

Пожалуйста, имейте в виду, что при компиляции в качестве предыдущей версии .NET вы можете потерять функциональность, такую ​​как асинхронные функции.