Переопределение MSBuildExtensionsPath в задаче MSBuild является ошибочным - PullRequest
5 голосов
/ 20 мая 2010

Это уже добавлено в MS Connect:

https://connect.microsoft.com/VisualStudio/feedback/details/560451

Я пытаюсь переопределить свойство $ (MSBuildExtensionsPath) при создании решения, содержащего проект веб-приложения на C #, через msbuild. Я делаю это, потому что файл csproj веб-приложения импортирует файл "$ (MSBuildExtensionsPath) \ Microsoft \ VisualStudio \ v9.0 \ WebApplications \ Microsoft.WebApplication.targets". Этот файл устанавливается Visual Studio в стандартную папку $ (MSBuildExtensionsPath) (C: \ Program Files \ MSBuild). Я хотел бы устранить зависимость от установки этого файла на компьютере (я хотел бы, чтобы мои серверы сборки были как можно более "чистыми"). Чтобы сделать это, я хотел бы включить Microsoft.WebApplication.targets в систему контроля версий в моем проекте, а затем переопределить $ (MSBuildExtensionsPath), чтобы csproj импортировал эту включенную версию Microsoft.WebApplication.targets. Этот подход позволяет мне удалить зависимость без необходимости вручную изменять файл csproj веб-приложения.

Эта схема прекрасно работает, когда я собираю файл решения из командной строки, предоставляя настраиваемое значение $ (MSBuildExtensionsPath) в командной строке для msbuild через флаг / p. Однако, если я пытаюсь построить решение, используя задачу MSBuild, в пользовательском файле проекта msbuild (переопределяя MSBuildExtensionsPath с помощью атрибута «Свойства»), произойдет сбой, поскольку файл csproj веб-приложения пытается импортировать объект Microsoft.WebApplication.targets из «стандартное» расположение Microsoft.WebApplication.targets (C: \ Program Files \ MSBuild). Примечательно, что если я запускаю msbuild с помощью задачи «Exec» в моем файле проекта, это работает. Еще более примечательно, что ПЕРВЫЙ раз, когда я запускаю сборку с помощью задачи «MSBuild». ПОСЛЕ того, как я запустил сборку с помощью задачи «EXEC» (или непосредственно из командной строки), сборка работает.

Кто-нибудь видел такое поведение раньше? Я сумасшедший? Кто-нибудь знает об основной причине этой проблемы, возможном обходном пути, или это законная ошибка в MSBuild?

Шаги для воспроизведения:

1) Создать новое пустое решение в MSVS 2008 (Fake.sln)

2) Добавить новое веб-приложение C # в решение (WebApplication1.csproj)

3) Закрыть MSVS

4) Скопируйте содержимое «C: \ Program Files \ MSBuild \» в каталог с именем «MSBuildExtensions» в каталоге, содержащем ваше решение.

5) переименуйте каталог «C: \ Program Files \ MSBuild \ Microsoft \ VisualStudio \ v9.0 \ WebApplications», чтобы WebApplication1.csproj не смог импортировать цели Microsoft.WebApplication.targets из этого расположения.

6) Создайте пользовательский файл проекта MSBuild с именем «TestBuild.proj» в том же каталоге, что и решение. Он должен иметь следующее содержание:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="BuildMSBuild">

<PropertyGroup>
    <MSBuildExtensionsPath>$(MSBuildProjectDirectory)\MSBuildExtensions\</MSBuildExtensionsPath>
    <BuildThis>Fake.sln</BuildThis>
</PropertyGroup>

<Target Name="BuildMSBuild">
    <MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);" Targets="Clean" />
    <MSBuild Projects="$(BuildThis)" Properties="MSBuildExtensionsPath=$(MSBuildExtensionsPath);"/>
</Target>

</Project>

7) выполнить «msbuild TestBuild.proj» из командной строки MSVS (примечание: сборка может завершиться успешно в первый раз, но не удастся, если вы запустите более одного раза)

Ответы [ 4 ]

4 голосов
/ 26 июня 2010

Вы пытались установить переменную среды MSBuildExtensionPath в приглашении CMD и затем запустить сборку?

Например:

C:\> SET MSBuildExtensionsPath=C:\My\MSBuild\Extensons

Тогда в этом файле проекта:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Build">
    <Message Text='MSBuildExtensionsPath="$(MSBuildExtensionsPath)"' />
  </Target>
</Project>

вы получите следующий вывод:

c:\Users\chuckeng\Desktop\ConsoleApplication1>"C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe" my.proj
Microsoft (R) Build Engine Version 3.5.30729.4926
[Microsoft .NET Framework, Version 2.0.50727.4927]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 6/25/2010 1:04:05 PM.
Project "c:\my.proj" on node 0 (default targets).
  MSBuildExtensionsPath="C:\My\MSBuild\Extensons"
Done Building Project "c:\my.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.03

Это работает и с v4.0. Хотя, поддержка, как правило, лучше в v4.0 для таких вещей. И, v4.0 на 100% обратно совместим (ошибки не выдерживают). Таким образом, вы можете собрать свой v3.5 и предыдущие проекты с v4.0. Просто выберите ToolsVersion 3.5.

msbuild my.proj /tv:3.5

Надеюсь, это поможет ...

Чак Англия Visual Studio Менеджер программ - MSBuild

3 голосов
/ 22 мая 2010

Это ошибка в MSBuild 3.5, но она исправлена ​​в MSBuild 4.

Если вы можете, переключитесь на MSBuild 4 (вы все еще можете скомпилировать свои проекты 3.5), в противном случае вам придется переопределить свойство в файле проекта.

3 голосов
/ 20 мая 2010

Работает нормально, если переопределить MSBuildExtensionsPath прямо в файле веб-приложения .csproj.

<PropertyGroup>
  <MSBuildExtensionsPath>C:\Users\madgnome\Desktop\msbuild</MSBuildExtensionsPath>

  <!-- It works too with relative path -->
  <!--<MSBuildExtensionsPath>..\msbuild</MSBuildExtensionsPath>-->
</PropertyGroup>

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
1 голос
/ 17 января 2013

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

<PropertyGroup>
  <MSBuildExtensionsPath Condition=" '$(MSBuildExtensionsPath64)' != '' ">$(MSBuildExtensionsPath64)</MSBuildExtensionsPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
...