注意:此解决方法不受 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.targets
and的文件中导入目标after.{YourSolution}.sln.targets
,如果这些文件存在的话。这是解决此 MSBuild 限制/错误的关键。