MSBuild-解决方案的特定于项目的目标不起作用 [英] MSBuild - Project-specific targets for solution does not work
问题描述
我有一个包含多个项目的解决方案,其中包括一个Web应用程序.我希望MSBuild对Web应用程序项目执行"WebPublish"目标,对解决方案中的所有其他项目执行默认目标".
I have a solution that has multiple projects in it, including a web application. I want MSBuild to execute "WebPublish" target against the web application project and "default target" for all other projects in the solution.
这篇MSDN文章说,我可以通过指定命令来做到这一点线
This MSDN article says that I can do it specifying the command line
msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean
但是我永远无法使它工作-MSBuild返回错误,诸如"NotInSlnFolder:Rebuild"目标之类的东西不存在.指定哪个目标,构建,重建或清理都没有关系-在任何情况下均不起作用.
But I never could make it work - MSBuild return an error, something like "NotInSlnFolder:Rebuild" target does not exist. It does not matter what target to specify, Build, Rebuild or Clean - it does not work in any case.
我如何实现为解决方案指定特定于项目的目标的目标?
How can I achieve my goal of specifying project-specific targets for a solution?
MSDN文档不起作用.还是我错过了什么?
The MSDN documentation does not work. Or have I missed something?
推荐答案
注意:此变通方法不受Microsoft正式支持,因此不能保证它将永远有效.
在包含SLN文件的文件夹中,创建文件before.{YourSolution}.sln.targets
,其内容如下:(将大括号中的内容替换为所需的内容.)
In folder with the SLN file, create the file before.{YourSolution}.sln.targets
, with the following content: (Replace what in curly brackets to whatever you need.)
<?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>
之后,您可以执行命令行:
After that you can execute the command line:
msbuild {YourSolution}.sln /t:{MyCompany_MyProduct_WebApp:WebPublish}
长答案
如果添加环境变量 MSBUILDEMITSOLUTION
,则将其值设置为1,MSBuild将不会删除为解决方案和项目生成的临时文件.
Long Answer
If you add environment variable MSBUILDEMITSOLUTION
, setting its value to 1, MSBuild will not delete temporary files generated for the solution and projects.
这将使您能够找到在解决方案文件夹中生成的{YourSolution}.sln.metaproj
和{YourSolution}.sln.metaproj.tmp
文件,它们只是标准的MSBuild项目文件.
This will allow you to find {YourSolution}.sln.metaproj
and {YourSolution}.sln.metaproj.tmp
files generated in the solution folder, which are just standard MSBuild project files.
对于 MSBuild 3.5 ,生成的文件为{YourSolution}.sln.cache
,并且保留该文件,而不考虑环境变量.分析这些文件,您将了解该过程的底层细节,并查看可用的自定义机会.
For MSBuild 3.5, the generated file is {YourSolution}.sln.cache
and is retained regardless of environment variables. Analyzing those files, you will understand low-level details of the process and to see the customization opportunities available.
在使用.Metaproj文件中的某些特定于项目的目标执行MSBuild之后,您会发现特定于项目的目标列表是硬编码的,并且仅支持标准目标 >(构建,重建,清理,编译,发布;请注意:发布和WebPublish不相同). MSBuild 3.5 仅生成清理,重建和发布目标以及仅带有项目名称的目标,即"Build".
After executing MSBuild with some project-specific target in the .Metaproj file you will find out that the list of project-specific targets is hardcoded and only standard targets are supported (Build, Rebuild, Clean, Compile, Publish; note: Publish and WebPublish are not the same). MSBuild 3.5 only generates Clean, Rebuild and Publish targets as well as a target with just the project's name that means "Build".
您还可以看到NotInSlnfolder:Rebuild
只是自动生成目标的名称.实际上,MSBuild不会解析它,也不在乎项目名称和位置.另外请注意,自动生成的目标名称(如果位于其中)使用解决方案文件夹层次结构指定项目名称. SolFolder\SolSubfolder\ProjectName:Publish
.
You also can see that NotInSlnfolder:Rebuild
is just a name of an autogenerated target. In reality MSBuild does not parse it and does not care about project names and location. Also note that the autogenerated target names specify the project name with solution folders hierarchy if it's in one, e.g. SolFolder\SolSubfolder\ProjectName:Publish
.
您会发现另一项至关重要的事情:MSBuild目标名称不支持点. 项目名称中的所有点均由下划线代替.例如,对于名为MyCompany.MyProduct.Components
的项目,您将必须在命令行中指定:
One more critically important thing you will find: The MSBuild Target Name does not support dots. All dots in project names are replaced with underscores. For example, for a project named MyCompany.MyProduct.Components
you will have to specify in the command line:
/t:MyCompany_MyProduct_Components:Rebuild
这就是为什么标准的特定于项目的目标Build都不起作用的原因-我的项目名称中包含了 dots .
That's why even standard project-specific target Build didn't work - my project name contained dots.
分析文件{YourSolution}.sln.metaproj.tmp
,您会发现在运行时它将尝试从名为before.{YourSolution}.sln.targets
和after.{YourSolution}.sln.targets
的文件中导入目标(如果存在).这是解决此MSBuild限制/错误的解决方法的关键.
Analyzing file {YourSolution}.sln.metaproj.tmp
, you will find out that at runtime it tries to import targets from file named before.{YourSolution}.sln.targets
and after.{YourSolution}.sln.targets
, if those files exist. This has a key to the workaround for this MSBuild limitation/bug.
这篇关于MSBuild-解决方案的特定于项目的目标不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!