【问题标题】:How do I call Visual Studio 2017 RC's version of MSBuild from a BAT file?如何从 BAT 文件调用 Visual Studio 2017 RC 版本的 MSBuild?
【发布时间】:2017-04-03 08:07:38
【问题描述】:

可以在此处找到早期版本的 MSBuild:%programfiles(x86)%\msbuild\<version>\bin\msbuild.exe.

但对于 Visual Studio 2017RC,路径是 %programfiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe。安装类型:企业、社区或专业,似乎是路径的一部分。这使得在 BAT 文件中指定 msbuild 的正确路径变得困难,该文件应该可以在具有不同版本 Visual Studio 2017 的许多不同计算机上运行。

从 bat 文件调用 Visual Studio 2017 RC 版本的 Msbuild 的最佳方法是什么?还是来自 PowerShell?

【问题讨论】:

  • 最好运行 vcvars,因为它通常包含 msbuild 的路径,或者对于 VS2017 也进行了更改?
  • vcvars 也在“企业”、“社区”或“专业”路径下。所以调用 vcvars 与调用 msbuild 一样未定义
  • 没有 VS150COMNTOOLS 或类似的环境变量来解决“企业”问题?
  • 也许他们这样做是因为可以在一台机器上安装企业/社区/...?无论如何,这有点糟糕。希望在发布时有所改变。
  • 问题是:用户可以安装任一版本(社区/专业/企业),但目录名称取决于版本

标签: msbuild visual-studio-2017


【解决方案1】:

支持的方式

VS2017 的安装引擎有一个互操作 API,可让您查询有关已安装 VS2017 实例的信息。有一个NuGet package,甚至还有a sample如何查询,包括安装路径。对于批处理或 PS 文件中的使用,您可能只需重写示例应用程序并从脚本中调用它以输出您需要的信息。

不支持的方式

VS 设置引擎将其数据存储在%ProgramData%\Microsoft\VisualStudio\Packages\_Instances 下。每个 VS2017 实例都会有一个文件夹,该文件夹内有一个 state.json 文件,其中包含有关该安装的信息,包括安装路径。

由于您需要从 .json 文件中提取信息,您可以选择编写从脚本文件调用的应用程序,或者直接在脚本中提供一些解析逻辑。 这显然很脆弱,因为 JSON 架构或文件位置可能会发生变化。

蛮力法

假设您使用的是默认安装路径,您可以在%ProgramFiles(x86)%\Microsoft Visual Studio\ 下递归搜索 msbuild.exe(似乎每个 VS 实例都会有 32 位和 64 位 msbuild.exe)。这可能是在您的脚本文件中最容易执行的操作,但确实依赖于默认安装路径(或您希望在其下搜索的任何硬编码路径)。

更改您的开发环境要求

您可以做的最后一件事是要求开发人员使用(或以某种方式调用)vsdevcmd.bat 来使用 VS 开发环境。这将使他们获得 MSBuild,以及 VS 环境中的任何其他工具,进入他们的 %PATH%。这确实对您的开发团队提出了要求,但始终是官方支持的查找 msbuild.exe 的方式。

【讨论】:

  • 另外:如果您从 Visual Studio 命令提示符运行 .bat 文件,msbuild 将位于路径上。
【解决方案2】:

如果您已安装 .NET Core 工具预览版 3 或更高版本,dotnet CLI 应默认在 %PATH% 上可用(即使您没有构建 .NET Core 项目),因此您可以试试dotnet msbuild。参考https://github.com/dotnet/docs/blob/master/docs/core/preview3/tools/dotnet-msbuild.md

【讨论】:

  • 可能行不通。在我的情况下,以The imported project "C:\Program Files\dotnet\sdk\2.1.402\Microsoft\VisualStudio\v15.0\Web\Microsoft.WebSite.Publishing.targets" was not found.结尾,即在dotnet安装下搜索MSBuild安装路径,而不是VS安装。
【解决方案3】:

Microsoft 已经创建了一个工具来查找 Visual Studio 2017 及更新版本https://github.com/Microsoft/vswhere的位置

this 博客文章中描述了该选项和更新的选项。

【讨论】:

  • 天哪,他们真的搞砸了...感谢您提供的链接(PowerShell 部分,在顶部,最适合我的构建)。
【解决方案4】:

现在 VS 2017 已经发布,觉得加我的 2 美分可能会有用:

创建批处理文件:

打开记事本

复制以下内容并粘贴到记事本中,将您要构建的解决方案替换为 [My Solution Name Here]:

@echo off

:variables
SET msBuildLocation="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
SET solutionDirectory=[My Solution Location Here]
SET batchFileLocation=[BatchFileLocation Here]

cd %solutionDirectory%

echo Building MS files for [My Solution Name Here].

call %msBuildLocation% [My Solution Name].sln /p:Configuration=Debug /m:4 /v:M /fl /flp:LogFile=msbuild.log;Verbosity=Normal /nr:false  /consoleloggerparameters:Summary;ShowTimestamp;ShowEventId;PerformanceSummary
echo -
echo --------Done building [My solution name here].--------------
echo -

cd %batchFileLocation%

使用 .bat 扩展名将您的批处理文件保存为您想要的任何文件。请务必选择所有文件而不是 .txt,否则它将不起作用。 通过发出保存它的 cd 命令来调用批处理文件,它应该可以工作。或者,只需双击。完成。

请注意,我的 Visual Studio 版本是社区版;您需要将路径替换为适当的版本。

【讨论】:

    【解决方案5】:

    我还从 CI 服务器上的 bat 文件运行构建工具:我找到的新位置是:

    %programfiles(x86)%\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe

    【讨论】:

      【解决方案6】:

      最简单的方法...

      • 利润;无论您的 VS SKU 是什么(专业/企业/社区都安装到不同的路径),构建工具都将安装到一个单独的位置,这是您安装它的任何地方的标准位置
      • 新位置C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe

      【讨论】:

      • 我遇到了一个问题,即 SSDT 不包含在 BuildTools 中。 SSDT 用于构建 .sqlproj 项目。
      • 我试过这个,但我的解决方案现在失败了,出现了非常基本的严重错误,例如“未找到 Visual Studio 命名空间”:S
      【解决方案7】:

      为仍在尝试在机器上找到最新版本的 msbuild 并在可用时回退到旧版本的人们发布此消息。我发现这个 powershell 的 sn-p 可以解决问题,它很容易成为 invoked from a bat file

      Function Find-MsBuild([int] $MaxVersion = 2017)
      {
          $agentPath = "$Env:programfiles (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe"
          $devPath = "$Env:programfiles (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe"
          $proPath = "$Env:programfiles (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe"
          $communityPath = "$Env:programfiles (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
          $fallback2015Path = "${Env:ProgramFiles(x86)}\MSBuild\14.0\Bin\MSBuild.exe"
          $fallback2013Path = "${Env:ProgramFiles(x86)}\MSBuild\12.0\Bin\MSBuild.exe"
          $fallbackPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319"
      
          If ((2017 -le $MaxVersion) -And (Test-Path $agentPath)) { return $agentPath } 
          If ((2017 -le $MaxVersion) -And (Test-Path $devPath)) { return $devPath } 
          If ((2017 -le $MaxVersion) -And (Test-Path $proPath)) { return $proPath } 
          If ((2017 -le $MaxVersion) -And (Test-Path $communityPath)) { return $communityPath } 
          If ((2015 -le $MaxVersion) -And (Test-Path $fallback2015Path)) { return $fallback2015Path } 
          If ((2013 -le $MaxVersion) -And (Test-Path $fallback2013Path)) { return $fallback2013Path } 
          If (Test-Path $fallbackPath) { return $fallbackPath } 
      
          throw "Yikes - Unable to find msbuild"
      }
      
      
      $msbuildPath = Find-MsBuild 2017
      

      【讨论】:

      • 谢谢。这非常有帮助。我必须在最后添加echo $msbuildPath 才能得到结果
      【解决方案8】:

      所以我有 2017 年社区版,对我来说路径是: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\

      此线程上的其他解决方案向我抛出了异常。

      【讨论】:

      • 为什么会被否决?我正要在这里寻找msbuild
      【解决方案9】:

      我维护了一个非常简单的 PowerShell 脚本 (gist) 来使用正确配置的 Visual Studio 环境变量运行 CI/CLI 构建。它使用vswhere.exeVsDevCmd.bat。作为 Azure DevOps 管道的一部分,它在构建代理上运行良好。特别是对于 C++ 项目,正确设置 INCLUDELIB 至关重要,这就是 VsDevCmd.bat 所做的。

      例如,使用MSBuild 为当前文件夹中的解决方案运行构建:

      powershell -f _invoke-build.ps1 -buildCommand "msbuild ."
      

      将 VS 的 INCLUDE 环境变量复制到剪贴板(为了好玩):

      powershell -f _invoke-build.ps1 -buildCommand "set INCLUDE | clip"
      

      脚本的当前版本:

      <#
        .Synopsis
          Find Visual Studio and run its VsDevCmd.bat, then run a build command.
      
        .Example
          powershell -f _invoke-build.ps1 -buildCommand "msbuild ."
      
        .Link
          https://gist.github.com/noseratio/843bb4d9c410c42081fac9d8b7a33b5e
      #>
      
      #Requires -Version 5.0
      # by @noseratio
      
      param([Parameter(Mandatory = $true)] [string] $buildCommand)
      Set-StrictMode -Version Latest
      $ErrorActionPreference = 'Stop'
      
      echo "Building via '$buildCommand' ..."
      
      $vs_not_found = "Visual Studio hasn't been detected!"
      
      $vswhere = "${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe"
      if (!(Test-Path $vswhere)) { throw $vs_not_found }
      
      $vs_ide_path = $(& $vswhere -format value -property productPath)
      if (!(Test-Path $vs_ide_path)) { throw $vs_not_found }
      
      $vs_ide_folder = "$(Split-Path $vs_ide_path)"
      $vs_dev_cmd = "$vs_ide_folder/../Tools/VsDevCmd.bat"
      $invoke = "call ""$vs_dev_cmd"" && cd ""$pwd"" && $buildCommand"
      
      # we need to run via CMD for proper propagation of Visual Studio environment vars
      & $env:comspec /s /c ""$invoke""
      if (!$?) { throw "Failed with error code: $LastExitCode" }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 2017-08-05
        • 2017-04-27
        • 1970-01-01
        • 1970-01-01
        • 2017-08-10
        • 1970-01-01
        相关资源
        最近更新 更多