MSBuild - 解决方案的项目特定目标不起作用

时间:2012-08-20 10:34:57

标签: msbuild msbuild-wpp

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

This MSDN article说我可以指定命令行

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

但我永远无法使其工作 - MSBuild返回错误,类似“NotInSlnFolder:Rebuild”目标不存在。指定,构建,重建或清理的目标无关紧要 - 它在任何情况下都不起作用。

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

MSDN文档不起作用。或者我错过了什么?

2 个答案:

答案 0 :(得分:39)

注意: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 仅生成清除,重建和发布目标以及目标,其中只有项目名称,即“构建”。

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

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

/t:MyCompany_MyProduct_Components:Rebuild

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

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

答案 1 :(得分:1)

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

akka.log-dead-letters标记内的

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

希望这对你有所帮助。