防止MSBuild在不使用解决方案配置的情况下在.sln中生成项目

防止MSBuild在不使用解决方案配置的情况下在.sln中生成项目,msbuild,teamcity,solution,azure-packaging,Msbuild,Teamcity,Solution,Azure Packaging,我想禁止在解决方案中构建某些项目(在TeamCity构建配置中,以优化提交构建反馈的速度,如果您必须知道的话) 我知道解决方案配置机制,但不想强迫大量的.sln文件以我希望能够关闭的每一种排列方式结束。我有一个基于约定的规则,我想说“如果我在做提交构建,我不想做最终的安装程序打包”。(我不想把它分解成一个单独的解决方案) 我不希望在.sln文件或通过[MsBuildEmitSolution][1]创建的.proj文件中使用涉及查找和替换的解决方案。我知道这里的问题涉及和 我看到MSBuild/v

我想禁止在解决方案中构建某些项目(在TeamCity构建配置中,以优化提交构建反馈的速度,如果您必须知道的话)

我知道解决方案配置机制,但不想强迫大量的
.sln
文件以我希望能够关闭的每一种排列方式结束。我有一个基于约定的规则,我想说“如果我在做提交构建,我不想做最终的安装程序打包”。(我不想把它分解成一个单独的解决方案)

我不希望在
.sln
文件或通过
[MsBuildEmitSolution][1]
创建的
.proj
文件中使用涉及查找和替换的解决方案。我知道这里的问题涉及和

我看到MSBuild
/v:diag
在说:

 2>Target "Build" in file "Z.sln.metaproj" from project "Z.sln" (entry point):
   Using "MSBuild" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
   Task "MSBuild"
     Global Properties:
       BuildingSolutionFile=true
         CurrentSolutionConfigurationContents=<SolutionConfiguration>
   <ProjectConfiguration Project="{C83D035D-169B-4023-9BEE-1790C9FE22AB}" AbsolutePath="X.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
   <ProjectConfiguration Project="{15E7887D-F1DB-4D85-8454-E4EF5CBDE6D5}" AbsolutePath="Y.csproj" BuildProjectInSolution="True">Debug|AnyCPU</ProjectConfiguration>
 </SolutionConfiguration>
2>从项目“Z.sln”(入口点)中选择文件“Z.sln.metaproj”中的目标“Build”:
使用程序集“Microsoft.Build.Tasks.v4.0,版本=4.0.0.0,区域性=中性,PublicKeyToken=b03f5f7f11d50a3a”中的“MSBuild”任务。
任务“MSBuild”
全局属性:
BuildingSolutionFile=true
当前解决方案配置内容=
调试|任意CPU
调试|任意CPU
因此,问题是:

是否有一种方法可以让我进行XPath替换或类似操作,从而对上面的项目Y产生更改
BuildProjectSolution=“
的效果


如果做不到这一点,我是否可以在
.ccproj
(Azure 1.4软件包)或
.csproj
(常规项目)文件中进行相对简单的编辑以产生影响(包括触发依赖项目)在命令行
msbuild Z.sln
解决方案生成中启用的项目是否为空?

您始终可以将要生成的特定项目作为参数传递给msbuild

MSBuild命令行如下所示:

MSBuild /t:<Project Name>:Rebuild;<Another Project Name>:Rebuild
MSBuild/t::Rebuild;:重建
在TeamCity中,您可以将
放在MSBuild runner的target字段中。

不确定它是否符合neat,但您可以设置
CustomAfterMicrosoftCommonTargets
导入
MSBuild
文件以覆盖
BuildDependsOn
属性,将其指向您自己的自定义生成任务。基本上,通过设置
CustomAfterMicrosoftCommonTargets
可以让msbuild导入包含以下内容的msbuild文件:

<PropertyGroup>
    <OldBuildDependsOn>$(BuildDependsOn)</OldBuildDependsOn>
    <BuildDependsOn>MyBuild</BuildDependsOn>
</PropertyGroup>

<Target Name="OldBuild" DependsOnTargets="$(OldBuildDependsOn)" />

<Target Name="MyBuild">
    <CallTarget Targets="OldBuild" Condition="<IfIWantThis>" /> 
</Target>

我在参数下添加了一个系统参数

  • 名称:
    system.ExcludeFromBuild
  • 种类:系统属性(
    系统。
  • 值:csproj的路径

自定义MSBuild文件没有问题。我不知道为什么这不符合整洁解决方案的要求。@Ritch Melton:我已经有了一个很棒的自定义msbuild文件来构建解决方案集(并行等,实现了极好的吞吐量)。我想要的是,产品中的子系统可以加载到VS中,并添加和删除项目-因此
.sln
文件。我曾指出,如果我能做的唯一一件事就是强迫MSBuild发出一个与之相当的.proj文件,那真是太悲哀了,因为每当MSBuild 5改变游戏时(或者当VS团队最终发现.sln文件不是特例时,这对真正的项目来说有点,嗯,很重要!),我觉得是的。sln文件问题是荒谬的。有几个msbuild问题以及它与VisualStudio的集成,我就是不理解。这句话太长了,不能在这里发表。@Ritch Melton:我通常不会让诸如长度之类的小问题妨碍我发泄:D谢谢你的回答。你是说(MSBuild被传递给一组顶级项目)是本机的还是(正如@Ritch Melton[似乎]所说的那样)我可以用它来代替
.sln
文件。首先,即使将上述任务拆分,也需要定制任务(可以是编译任务,也可以是基于PS或C#TaskFactory的任务)。我可能想不明白你的意思,一直在关注我,坐在5.sln文件中如何获得其中的50个
.csproj
/
.ccproj
s,而没有名为
*.AzurePackage
的项目(或者可能没有
*.ccproj
s)无需将VS SLN作为grouping@Ruben巴特林克:我相信你可以通过一系列的顶级项目。这需要大量键入(将50个目标传递到msbuild命令行),但不需要创建新目标或修改sln/csproj文件。我想看一个例子。至于它是否解决了我的问题,我仍然没有能力拥有一个包含14个项目的sln文件,让某人在其中添加一个新项目,并为给定的配置禁用另一个项目,这反映在我运行build+1有趣的技术时发生的事情中。我不认为这是一种基于一些声明性规则在解决方案中选择性地影响项目子集的构建与否的特别合适的方法——我必须动态生成CustomAfterMicrosoftTargets,才能使用这个攻角实现这一点……我不确定这是真的。我使用的方法是使用静态msbuild文件
ShouldBuild
。此文件包含一个
UsingTask
(因此我可以使用c#inline,因为我讨厌msbuild),它根据一些输入属性返回true或false。目前我只接受
$(MSBuildProjectFullPath)
,如果它是安装程序或路径中有
原型,则返回false。但我可以获取多个属性,包括正则表达式字符串、XPath字符串,或者任何可以用来确定
<Target Name="MyBuild">
    <CallTarget Targets="OldBuild" Condition="('$(IncludeInBuild)'=='' OR
    '$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath),
    $(IncludeInBuild), 
    System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='True') AND 
    ('$(ExcludeFromBuild)'=='' OR 
    '$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath), 
    $(ExcludeFromBuild),  
    System.Text.RegularExpressions.RegexOptions.IgnoreCase))'=='False')" /> 
</Target>