使用msbuild的特定版本构建项目或解决方案时,可以使用/toolsversion或/tv开关选择早期的.net工具链:
1
| "C:\\Program Files (x86)\\MSBuild\\14.0\\bin\\msbuild" /tv:12.0 amazing.sln |
根据以上所述,这对于msbuild的所有版本以及csc.exe等的版本均适用。
1 2 3 4 5 6 7 8 9 10 11
| >"C:\\Program Files (x86)\\MSBuild\\14.0\\bin\\msbuild" /tv:4.0 amazing.sln
...
CoreCompile:
C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Csc.exe ...
...
>"C:\\Program Files (x86)\\MSBuild\\14.0\\bin\\msbuild" /tv:12.0 amazing.sln
...
CoreCompile:
C:\\Program Files (x86)\\MSBuild\\12.0\\bin\\Csc.exe ...
... |
如果我未指定/tv,则取决于我使用的msbuild版本和许多环境变量,我可能会得到以下任何一项:
-
在项目文件的顶级元素中指定的ToolsVersion
-
与我使用的msbuild.exe版本相对应的ToolsVersion
-
msbuild.exe.config中的值
-
注册表中的值
(请参阅MSDN上的"覆盖工具版本设置"页面的不同版本)。
因此,为了使构建在构建服务器和本地计算机上具有一致的结果,我在运行msbuild.exe时使用/tv(实际上,这是在psake脚本中强制执行的,这也确保了它使用msbuild.exe的相应版本)。
但是,在使用Visual Studio构建时,不能使用/tv开关。而是,Visual Studio 2013及更高版本将使用该版本的Visual Studio附带的.net工具链,除非:
-
设置环境变量MSBUILDLEGACYDEFAULTTOOLSVERSION并...
-
...所有项目文件的ToolsVersion属性都设置为我要使用的版本。
这是如此巴洛克,以至于我无法相信任何人实际上正在这样做。因此,我的问题是:
-
有人在做MSBUILDLEGACYDEFAULTTOOLSVERSION事情吗?
-
如果不是,是否还有其他方法可以使Visual Studio使用特定的ToolsVersion而不使用该ToolsVersion附带的Visual Studio版本?可以存储在版本控制中(例如存储在项目或其他设置文件中)的东西将是理想的。
最后:
-
我什至应该在乎吗?鉴于C#编译器的每个后续版本都应该能够处理以前版本的输入,并且我可以在项目文件中设置目标.net框架和C#语言级别,是否足以确保可重复的构建?
(我的偏见是我应该关心,因为:
-
我希望在IDE和构建服务器上的构建相同(当然)
-
我希望能够使用VS2015(及以后的版本),因为它比以前的版本更好,但我不想在我决定使用之前使用新的工具链。
也许我想要太多...)
有关问题的具体示例,请参见我在github上的msbuild-vs-vs2015-toolsversion存储库。
一些背景:我问这个问题是因为最近我的一位同事提交了C#6.0代码,该代码可以用Roslyn在Visual Studio 2015的副本上很好地编译,但是在CI中失败,因为我们使用的是以前版本的C#构建错误。 .net工具链(他们使用了没有设置器的自动属性,在Roslyn中很好,但在较早的版本中没有)。我们将把CI版本更新为Roslyn,但我想看看我们是否可以防止将来发生这种情况。
-
固定:D大问题,顺便说一句
-
@alexandrul:谢谢。 我知道它的时间很长,但是我认为细节很重要。 很高兴提出任何建议的改进。
-
我问了同样的问题,但没有有效的答案。 在我看来,这是一个Microsoft错误,因为上述方法均无效。 stackoverflow.com/questions/33791934/
-
啊,我看到了盖伊,您试图回答我的问题,但这没有用。 仅使用已安装的VS2015进行尝试,它始终默认为14.0。
我通过编写一个Visual Studio扩展来解决此问题,该扩展在构建期间会临时设置环境变量MSBUILDDEFAULTTOOLSVERSION。从与.sln文件位于同一目录中的文件.toolsversion中读取要使用的值。 psake脚本读取相同的.toolsversion文件,并将该值传递给/tv开关。
扩展的代码可以在这里找到:https://github.com/guyboltonking/set-toolsversion-extension。令人遗憾的是,目前我还没有使用C ++或Visual Studio,因此我无法为其提供任何支持(但是我可以告诉你我使用它几个月都没有任何问题)。
感谢@efaruk提醒我MSBUILDDEFAULTTOOLSVERSION的存在。
编辑:感谢@ mbadawi23,现在可以将扩展名与VS2015和VS2017一起使用。
-
真是的另一个低调的推论:有人能启发我这一点吗?
-
我正在尝试在VS2015中使用您的扩展程序。我认为即时通讯使用正确,但是即时通讯出现以下行为:Setting MSBUILDDEFAULTTOOLSVERSION to 12.0 4>Building with tools version"14.0".当然,这会导致构建失败。
-
@ mbadawi23我不能提供太多帮助,因为我不再在可以运行VS2015的平台上工作。我唯一想到的是MSBUILDDEFAULTTOOLSVERSION是可以设置ToolsVersion的一长串东西中的最后一件事。列表中的所有其他项目将覆盖它。您可能要检查是否设置了任何其他环境变量。除此之外,我很抱歉自己一个人说:
-
谢谢您的答复。但是我设法使它起作用。我清理了解决方案,然后重新启动了VS2015。在此期间,我升级到VS2017,并在此处从您的存储库创建了一个fork
要在Visual Studio 2015中强制使用特定的C#版本,可以进入项目属性->构建->高级->语言版本。
如果将其设置为5,则编译器将抱怨C#6的功能:C#5中没有功能'...'。请使用语言版本6或更高版本。
另外,ReSharper也为此提供了一些工具。
-
抱歉,这不是问题所在。解决的问题是,即使使用相同版本的语言,.net工具链的不同版本也会产生不同的结果,并且没有一种在IDE中强制执行工具链版本的简单方法。我不赞成这个答案,因为它不能回答问题。
-
对于我来说,这是一个有用的解决方法,可用于识别违规代码并在VS2015中产生与在构建服务器上看到的相同的结果。显然,这不是一个长期的解决方案,但是很有帮助。
注意:您始终可以创建一个msbuild文件来通过使用它或自行更改项目来构建您的项目,并且可以有条件地确定工具版本(https://msdn.microsoft.com/zh-cn/library/7z253716.aspx )(。csproj还是具有不同扩展名的结构化msbuild脚本,它也将与VS兼容)。
问候...
编辑:
https://msdn.microsoft.com/zh-CN/library/bb383985.aspx
by setting the $(ProjectToolsVersion) property on a project within a solution. This lets you build a project in a solution with a Toolset version that differs from that of the other projects.
所以,我认为您已经得到了答案;)
-
此外,除非您检查当前工具版本,然后重新调用所需的工具版本,否则我看不到如何编写自己的MSBuild文件(扰流器:我们有几个自定义MSBuild文件)如何以编程方式设置ToolsVersion。比赛。嗯感觉还不错。我可以尝试一下...
-
您是否尝试过从VS Command Prompt!构建项目?从vs命令提示符进行构建与从vs进行构建是同一件事(相同的行为),VS会自行调用msbuild自身来构建项目。没有其他管道。您说的工具版本意思不同吗?
-
另外,您应使用不同/所需的msbuild版本构建所有项目,以确保兼容性/可移植性。要做的另一项相关任务是使用.Net可移植性分析器检查可移植性:visualstudiogallery.msdn.microsoft.com/
-
感谢您抽出宝贵的时间来答复,但我不确定您是否已完全理解该问题。 Ive清楚地表明了Ive是从命令提示符构建的。另外,调用msbuild.exe并在VS中进行构建是相似的,但并不完全相同,主要要点是,在VS中进行构建时,我无法为msbuild指定任何参数,尤其是tv参数。最后,可移植性很重要,但构建可复制性也很重要,这是问题所在。
-
因此,创建一个environment.msbuild文件并将其链接到您的.csproj文件(或vbproj文件等)中(项目导入:msdn.microsoft.com/zh-cn/library/92x05xfs.aspx)。您怎么说这是公平的..ish。这是您正在寻找的解决方案;)。对于msbuild和VS,您可以具有相同的行为(如果可以编写一个好的msbuild脚本)...
-
也许您可以演示(编辑答案)这样的文件是什么样子?我们的目标是使用14.0以外的ToolsVersion使VS2015编译.csproj。说12.0。
-
在前面的评论中,我进一步提出:使用所需的toolsversion进行重新调用,如下所示:,由于调用后调用者将继续使用原始不需要的ToolsVersion继续正常构建,因此无法正常工作(或至少不容易)。 。此外,这已经变得太巴洛克了,我宁可避免这种事情。
-
谢谢:我之前已经阅读过MSDN中的该节,但是在项目文件本身中设置ProjectToolsVersion无效:在VS2015中进行构建时,我们仍然使用14.0 ToolsVersion。你有试过吗?奏效了吗?如果是这样,您能告诉我如何在解决方案内的项目上设置$(ProjectToolsVersion)属性吗?
-
我无法使您提出的任何解决方案都能正常工作,而且我担心会出现交叉用途,因此我在github上建立了一个存储库来演示原始C#控制台项目中的问题。如果有时间,请向您展示如何修改该项目以使其在VS2015 IDE中构建(确保您的答案中包含所有修复程序,如果可行,我将很乐意接受!)。
-
我的系统上没有vs 2013,因此无法模拟对不起。但是,如果您引用同一文档(msdn.microsoft.com/en-us/library/bb383985(v=vs.140).aspx),则可以看到另一个选项:6.如果未设置环境变量MSBUILDLEGACYDEFAULTTOOLSVERSION,则使用以下步骤:如果环境变量MSBUILDDEFAULTTOOLSVERSION设置为存在的ToolsVersion,请使用它。如果在MSBuild.exe.config中设置了DefaultOverrideToolsVersion,请使用它。如果在注册表中设置了DefaultOverrideToolsVersion,请使用它。否则,请使用当前的ToolsVersion。
-
感谢您提及MSBUILDDEFAULTTOOLSVERSION;我已经忘记了这一点,这使我想到了(比我希望的要复杂得多)的解决方案。
-
@GuyBoltonKing-我建议进行编辑,删除您指出的答案的不正确部分(关于.bat文件)
您在Visual Studio中看到的内容(工具等)及其背后的代码不是已包含在已编译数据中的内容,它们只是视觉/可读的表示形式,当将它们编译为VS的早期版本时,您将使其成为可执行文件。版。
请记住,如果编译为以前的.NET版本,则可能会丢失诸如异步功能之类的功能。
-
谢谢,但这不能回答问题。我知道针对早期版本的.NET进行编译将为我提供不同的功能,但这不是问题所在。所针对的.NET版本和ToolsVersion是相互独立的:我可以使用ToolsVersion 12.0和14.0针对.NET 2.0、4.0、4.5.1等进行构建。我可以使用项目设置来控制.NET版本。问题是关于我如何控制ToolsVersion。因此,我拒绝了您的回答。