这已经在 MS Connect 上交叉发布:
https://connect.microsoft.com/VisualStudio/feedback/details/560451
在通过 msbuild 构建包含 C# Web 应用程序项目的解决方案时,我试图覆盖属性 $(MSBuildExtensionsPath)。我这样做是因为 Web 应用程序 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 版本。
当我从命令行构建解决方案文件时,此方案工作正常,通过 /p 标志在命令行向 msbuild 提供 $(MSBuildExtensionsPath) 的自定义值。但是,如果我尝试使用自定义 msbuild 项目文件中的 MSBuild 任务构建解决方案(使用“Properties”属性覆盖 MSBuildExtensionsPath),则会失败,因为 Web 应用程序 csproj 文件正在尝试从“标准”Microsoft.WebApplication.targets 位置(C:\Program Files\MSBuild)。值得注意的是,如果我使用自定义项目文件中的“Exec”任务运行 msbuild,它就可以工作。更值得注意的是,在我使用“EXEC”任务(或直接从命令行)运行构建之后,我第一次使用“MSBuild”任务运行构建,构建工作正常。
有没有人见过这样的行为?我疯了吗?是否有人知道此问题的根本原因、可能的解决方法,或者这是否是 MSBuild 中的合法错误?
重现步骤:
1) 在 MSVS 2008 (Fake.sln) 中创建一个新的空解决方案
2) 将新的 C# Web 应用程序添加到解决方案 (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) 在与解决方案相同的目录中创建一个名为“TestBuild.proj”的自定义 MSBuild 项目文件。它应具有以下内容:
<?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) 在 MSVS 命令提示符下执行“msbuild TestBuild.proj”(注意:第一次构建可能会成功,但如果多次运行则会失败)