使用msbuild和devenv交换构建相同的解决方案

时间:2014-03-28 02:20:22

标签: visual-studio visual-studio-2012 msbuild

经常发生这种情况,我首先使用msbuild在命令行上构建一些解决方案,运行它一段时间,然后发现我需要更改和调试它。因此,我在Visual Studio中打开它,最终在Visual Studio中构建它。

即使我什么都没改变,VS还是会重建解决方案的很多部分!

深入研究以下内容:

在Visual Studio中构建生成空的cs文件并将它们注入Compile项目组。当然,它们比已经构建的二进制文件更新,因此devenv.exe重建了很多项目。感谢TemporaryGeneratedFile_[guid] in /obj/debug breaking build

这是一个真正的无赖。我通过重命名Microsoft.WorkflowBuildExtensions.targets文件来禁用此行为 - 我不做工作流程。

我想我可以入侵CoreCompileDependsOn并以某种方式中和Microsoft.WorkflowBuildExtensions.targets中的GenerateCompiledExpressionsTempFile目标,但这必须在190个项目中完成!这是一个严重的变化。

devenv.exe似乎关心一些文件总是被复制到输出目录,即使msbuild认为它不是问题。

确实,这是devenv.exe构建日志中的一行:

Project 'HRCore.Tests' is not up to date. Project item 'C:\abc\UI\HRCore.Tests\HRImport\Import_missing_state_county.xml' has 'Copy to Output Directory' attribute set to 'Copy always'.

那又怎样? msbuild并不关心它,但devenv确实如此。这个文件不是HRCore.Tests的依赖项,而且msbuild是正确的。

与此同时,我将其从Always更改为PreserveNewest

无论如何,我很想知道如何消除这些差异。

例如,即使使用msbuild进行构建,将BuildingInsideVisualStudio设置为true也是一个好主意吗?

有什么想法吗?

P.S。

我们构建.NET和Silverlight。控制台应用程序,dll和Web应用程序。

2 个答案:

答案 0 :(得分:2)

由于明确检查.targets$(BuildingInsideVisualStudio)文件确实导致Visual Studio和命令行MsBuild之间出现不同的行为:

  <PropertyGroup>
    <PrepareResourcesDependsOn>
      ValidationExtension;
      ExpressionBuildExtension;
      $(PrepareResourcesDependsOn)
    </PrepareResourcesDependsOn>
  </PropertyGroup>

  <PropertyGroup>
    <!-- Explicit check for Visual Studio here -->
    <CoreCompileDependsOn Condition="'$(BuildingInsideVisualStudio)' == 'true'">
        GenerateCompiledExpressionsTempFile;
        $(CoreCompileDependsOn)
    </CoreCompileDependsOn>   
  </PropertyGroup>

显式检查使我的配置中的Visual Studio中出现临时文件生成 。制作这些文件是为了在Visual Studio中运行时可以进入它们并调试它们。

可以通过在项目文件中覆盖<GenerateCompiledExpressionsTempFilePathForEditing />来清空行为,以便在命令行上明确清除它的值。

/p:GenerateCompiledExpressionsTempFilePathForEditing=''

这是保护此行为的条件:

 <Target Name ="GenerateCompiledExpressionsTempFile" 
      Condition = "'$(GenerateCompiledExpressionsTempFilePathForEditing)' != ''">  

查看MsBuild路径,您应该能够通过在命令行上传递/p:DisableWorkflowCompiledExpression=true来完全关闭已编译表达式的生成。

您也可以覆盖CoreCompileDependsOn并从中删除GenerateCompiledExpressionsTempFile;项。

当有特殊行为时,这真的很可怜。在编辑器中进行buildign时。最后,我总是错误地使Visual Studio表现为MsBuild,而不是相反。当BuildingInsideVisualStudio成立时,许多其他目标将承担特殊服务或主机编译器的可用性,使得MsBuild在Visual Studio中认为它实际上并不是一个非常糟糕的主意。

答案 1 :(得分:0)

此页面上另一个有用的解决方案建议了几种替代方法,其中显然最好的方法是从GenerateCompiledExpressionsTempFile属性中删除CoreCompileDependsOn目标。不幸的是,该属性是MSBuild 属性,而不是MSBuild item ,因此删除其中的特定部分并非一帆风顺。 sup> [注1。]

这也许就是为什么@jessehouwing继续建议其他方法来阻止 Microsoft.WorkflowBuildExtensions 目标的运行-并因此将这三个烦人的.cs文件添加到每个,即通过调整目标确定在决定做什么时要检查的一些环境MSBuild值。

那么,现在对我的一小笔贡献...当您可以简单地将整个 Target 自身空白掉时,为什么要操纵不需要的目标考虑的因素,试图诱使它不要运行?

只需将以下行添加到.csproj项目文件的底部:

    ...etc...
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <Target Name="GenerateCompiledExpressionsTempFile" />          <!-- add this line -->
</Project>



注释:
1.例如,可以使用内联$([System.String]::Replace(...)) MSBuild 中从属性中删除定界项目。