MSBuild-解决方案的特定于项目的目标不起作用 [英] MSBuild - Project-specific targets for solution does not work

查看:164
本文介绍了MSBuild-解决方案的特定于项目的目标不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个项目的解决方案,其中包括一个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.targetsafter.{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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆