27

我有一个包含多个项目的解决方案,包括一个 Web 应用程序。我希望 MSBuild 对 Web 应用程序项目执行“WebPublish”目标,并为解决方案中的所有其他项目执行“默认目标”。

这篇 MSDN 文章说我可以指定命令行

msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean

但我永远无法让它工作 - MSBuild 返回一个错误,类似于“NotInSlnFolder:Rebuild”目标不存在。指定什么目标(构建、重建或清理)并不重要——它在任何情况下都不起作用。

如何实现为解决方案指定项目特定目标的目标?

MSDN 文档不起作用。还是我错过了什么?

4

2 回答 2

40

注意:此解决方法不受 Microsoft 官方支持,因此不能保证它会永远有效。


简答

在包含 SLN 文件的文件夹中,创建文件before.{YourSolution}.sln.targets,其内容如下:(将大括号中的内容替换为您需要的任何内容。)

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="{MyCompany_MyProduct_WebApp:WebPublish}">
    <MSBuild
        Condition="'%(ProjectReference.Identity)' == '{$(SolutionDir)MyCompany.MyProduct.WebApp\MyCompany.MyProduct.WebApp.csproj}'"
        Projects="@(ProjectReference)"
        Targets="{WebPublish}"
        BuildInParallel="True"
        ToolsVersion="4.0"
        Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"
        SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)" />
  </Target>
</Project>

之后,您可以执行命令行:

msbuild {YourSolution}.sln /t:{MyCompany_MyProduct_WebApp:WebPublish}

长答案

如果添加环境变量 MSBUILDEMITSOLUTION,将其值设置为 1,MSBuild 将不会删除为解决方案和项目生成的临时文件。

这将允许您查找在解决方案文件夹中生成{YourSolution}.sln.metaproj{YourSolution}.sln.metaproj.tmp文件,这些文件只是标准的 MSBuild 项目文件。

对于MSBuild 3.5{YourSolution}.sln.cache ,无论环境变量如何,都会保留生成的文件。分析这些文件,您将了解流程的底层细节并查看可用的定制机会。

在 .Metaproj 文件中使用某些特定于项目的目标执行 MSBuild 后,您会发现特定于项目的目标列表是硬编码的,并且仅支持标准目标(构建、重建、清理、编译、发布;注意:发布和 WebPublish不一样)。MSBuild 3.5仅生成 Clean、Rebuild 和 Publish 目标以及仅具有项目名称的目标,即“构建”。

您还可以看到这NotInSlnfolder:Rebuild只是一个自动生成的目标的名称。实际上,MSBuild 不会解析它,也不关心项目名称和位置。另请注意,自动生成的目标名称指定具有解决方案文件夹层次结构的项目名称(如果它在一个中),例如SolFolder\SolSubfolder\ProjectName:Publish.

您会发现另一件至关重要的事情:MSBuild 目标名称不支持点项目名称中的所有点都替换为下划线。例如,对于一个名为的项目,MyCompany.MyProduct.Components您必须在命令行中指定:

/t:MyCompany_MyProduct_Components:Rebuild

这就是为什么即使是标准的项目特定目标 Build 也不起作用 - 我的项目名称包含

分析 file {YourSolution}.sln.metaproj.tmp,您会发现在运行时它会尝试从名为before.{YourSolution}.sln.targetsand的文件中导入目标after.{YourSolution}.sln.targets,如果这些文件存在的话。这是解决此 MSBuild 限制/错误的关键。

于 2012-08-22T21:51:01.183 回答
1

您可以在文本编辑器中打开解决方案文件并检查以下行是否存在,如果不存在,则可以添加

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><Project>标签内。

希望这对您有所帮助。

于 2016-07-15T12:45:17.680 回答