我有一个包含多个项目的解决方案,包括一个Web应用程序。我希望MSBuild针对Web应用程序项目执行“WebPublish”目标,并为解决方案中的所有其他项目执行“默认目标”。
This MSDN article说我可以指定命令行
msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean
但我永远无法使其工作 - MSBuild返回错误,类似“NotInSlnFolder:Rebuild”目标不存在。指定,构建,重建或清理的目标无关紧要 - 它在任何情况下都不起作用。
如何实现为解决方案指定项目特定目标的目标?
MSDN文档不起作用。或者我错过了什么?
答案 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.targets
和after.{YourSolution}.sln.targets
的文件中导入目标,如果这些文件存在的话。这有关于此MSBuild限制/错误的解决方法的关键。
答案 1 :(得分:1)
您可以在文本编辑器中打开解决方案文件并检查是否存在以下行,如果没有则可以添加
akka.log-dead-letters
标记内的 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
。
希望这对你有所帮助。