我有中有多个项目,其中包括Web应用程序的解决方案。 我想的MSBuild执行对Web应用程序项目“WebPublish”的目标和“默认目标”解决方案中的所有其他项目。
这MSDN文章说,我可以做到这一点指定命令行
msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean
但我从来没有能够使它发挥作用 - 的MSBuild返回一个错误,像“NotInSlnFolder:重建”目标不存在。 不要紧,指定什么样的目标,新建,改建或清洁 - 它不会在任何情况下工作。
我怎样才能实现我指定一个解决方案项目的具体目标的目标是什么?
MSDN文档无法正常工作。 还是我错过了什么?
注意:此变通办法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项目文件。
为3.5的MSBuild,所生成的文件是{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
这就是为什么即使标准项目的具体目标构建没有工作-我的项目名称包含点 。
分析文件{YourSolution}.sln.metaproj.tmp
,你会发现,在运行时,它会尝试从指定的文件中导入目标before.{YourSolution}.sln.targets
和after.{YourSolution}.sln.targets
,如果这些文件存在。 这有一个关键的办法解决这个MSBuild的限制/错误。
您可以在文本编辑器中打开您的解决方案文件,并检查是否包含以下行存在或不如果不是,那么你可以添加
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
内<Project>
标记。
希望这帮助你。