使用msbuild和devenv可互换地构建相同的解决方案

问题描述:

我经常使用msbuild在命令行上构建一些解决方案,运行一段时间,然后发现需要更改和调试它。所以,我在Visual Studio中打开它,并最终在Visual Studio中构建它。使用msbuild和devenv可互换地构建相同的解决方案

发生什么是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应用程序。

+0

我对此有点惊讶 - 最近我一直在尝试设置一个自定义构建步骤,因为VS和MSB有不同的增量构建方法,但是我认为VisualStudio更聪明。这可能是因为你在某些项目中设置了一些稍微更奇怪的设置,使得它想要复制东西 –

+0

不要那么确定。检查你是否有'Microsoft.WorkflowBuildExtensions.targets'文件。如果你这样做 - 放心,你的obj目录包含我提到的奇怪文件。接下来尝试在VS中使用诊断设置进行编译 - 您会看到VS抱怨由于一些文件被复制到Always输出而导致项目不是最新的。 – mark

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

<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;项目。

在编辑器内部构建编辑器时,如果出现“特殊行为”,这确实是一件可疑的事情。最后,我总是会犯错,让Visual Studio像MsBuild一样行事,而不是相反。当BuildingInsideVisualStudio为真时,许多其他目标将承担特殊服务或主机编译器的可用性,但让MsBuild认为它在Visual Studio内部看起来是一个非常糟糕的主意,而实际上它不是。

+0

你使用什么版本的VS? – mark

+0

我已经安装了2010〜2015RC。但是有问题的目标文件存在于.NET框架目录中,所以我认为更好的问题是,您定位的是哪个Framework版本。这些示例来自v4.0框架目录。 – jessehouwing