【问题标题】:Programmatically finding the VS2017 installation directory以编程方式查找VS2017安装目录
【发布时间】:2017-04-27 15:31:24
【问题描述】:

使用以前版本的 VS,您可以查询注册表以确定 VS 的安装目录:

HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0

但是,这似乎不适用于 VS2017 RC。我们有脚本可以检测最新安装的 VS,然后做“正确的事情”,到目前为止,我在将 VS2017 插入这些系统时遇到了问题。

有人知道如何以编程方式确定 VS2017 的安装位置吗?

【问题讨论】:

  • 应用程序应该使用Wow 节点。它们仅存在于 x64 系统中以允许 x86 应用程序工作。你检查过HKLM\SOFTWARE\Microsoft\VisualStudio\15.0\Setup 节点吗?不管怎样,磁盘布局已经改变了很多。现在几乎所有内容都可以在 `%PROGRAM FILES%\Microsoft Visual Studio 15.0` 中找到

标签: visual-studio visual-studio-2017


【解决方案1】:

Visual Studio 2017 支持所有 SKU(企业版、专业版和社区版)的无注册并行安装。

MSI 安装程序可以通过此处描述的 API 进行查询: https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/

例子在这里:

【讨论】:

  • 我认为这是某种并排的东西 - 感谢您的链接!
【解决方案2】:

你可以使用这个PowerShell sn-p来查找VS2017的安装目录:

$vssetup_path = "$([Environment]::GetFolderPath("MyDocuments"))\WindowsPowerShell\Modules\VSSetup"
if (-not (Test-Path $vssetup_path -pathType container))
{
    iwr https://github.com/Microsoft/vssetup.powershell/releases/download/1.0.36-rc/VSSetup.zip -OutFile "$env:TEMP\VSSetup.zip"
    Expand-Archive "$env:TEMP\VSSetup.zip" $vssetup_path
}
$vs2017 = Get-VSSetupInstance -All | Select-VSSetupInstance -Require 'Microsoft.VisualStudio.Workload.NativeDesktop' -Version '[15.0,16.0)' -Latest
"Installation Path: " + $vs2017.InstallationPath
#`vsdevcmd.bat -arch=x86` or `vsdevcmd.bat -arch=amd64` can be used to setup path's to VC++ compiler
"VsDevCmd.bat Path: " + $vs2017.InstallationPath + "\Common7\Tools\VsDevCmd.bat"

【讨论】:

  • 嘿,你试图把模块偷偷溜进我的系统?。无论如何它在我的系统上失败了......(-not (Test-Path $vssetup_path -pathType container)) -eq 0所以模块没有安装
【解决方案3】:

我可以推荐我的包 get-vs2017-path,它只使用内置的 Windows 工具(虽然它是作为 NPM 包构建的,但它没有依赖项,并且工具文件夹独立工作)

【讨论】:

    【解决方案4】:

    我使用类似于 KindDragon 建议的 powershell

    $Is64bitOs = $env:PROCESSOR_ARCHITEW6432 -eq 'AMD64';
    if ($Is64bitOs){
        $registryPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0";
    }
    else {
        $registryPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\14.0";
    }
    
    $VSInstallDir = (Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0 -Name ShellFolder).ShellFolder;
    

    【讨论】:

    • 这是通向 VS2015 的路径,而不是 2017
    • 我不确定VS2017新版本,但可能将14.0更改为15.0?
    • 不,VS2017 不使用注册表
    【解决方案5】:

    您可以使用vswhere工具获取VS2017的位置。

    例子:

    @echo off
    
    rem VS2017U2 contains vswhere.exe
    if "%VSWHERE%"=="" set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
    
    for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
      set InstallDir=%%i
    )
    
    if exist "%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" (
      "%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" %*
    )
    

    您可以在此处阅读更多信息:https://blogs.msdn.microsoft.com/heaths/2017/02/25/vswhere-available/

    【讨论】:

    • 我换成这个作为接受的答案,因为它为我提供了一个如何编写脚本来获取路径的示例。
    • 这对我来说不太奏效 - 请在我的回答中查看我需要做的更改。
    • 如果vswhere 在默认情况下不在路径上,则此方法有效。请参阅下面@Srekel 的答案...
    • vswhere 是一个独立的 exe,因此您可以随时将其复制到您想要的任何位置
    • "%VSWHERE%" -latest 如果您同时安装了 VS2017 和 VS2019,可能不是最好的主意;您可以尝试 "%VSWHERE%" -version [15.0,16.0) 虽然精确定位到 VS2017
    【解决方案6】:

    由于批处理的“延迟扩展”“功能”,KindDragon 的解决方案不太适合我。 (笏)

    这是我的代码,兼容 VS 2017 15.2(用于 vswhere.exe 安装)

    SETLOCAL EnableDelayedExpansion
    
    if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
      echo "WARNING: You need VS 2017 version 15.2 or later (for vswhere.exe)"
    )
    
    for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
      set InstallDir=%%i
    )
    
    if exist "!InstallDir!\VC\Auxiliary\Build\vcvars64.bat" (
      call "!InstallDir!\VC\Auxiliary\Build\vcvars64.bat"
    ) else (
      echo "Could not find !InstallDir!\VC\Auxiliary\Build\vcvars64.bat"
    )
    

    特别注意 SETLOCAL EnableDelayedExpansion 和 !InstallDir!

    【讨论】:

    • 我看不到 KindDragon 的解决方案中的延迟扩展因素有多大——只有环境变量的“set”和“get”嵌套在单个语句中时才有意义……因为它代表他的解决方案对我有用
    • 我不知道。我将它粘贴到我的批处理文件中,但它不起作用,似乎是因为它没有在运行时扩展 InstallDir 变量。然后我使用了 EnabledDelayedExpansion,它对我有用。我讨厌批处理文件,也不太想了解哪里出了问题,很高兴找到了解决方案:D 发布它希望它可以帮助其他人。
    • 这个 sn-p 确实有效,因为它不假定 vswhere 在路径上。对于那些想知道延迟扩展的人,它所做的只是在循环和条件块中使用!somevar! 语法启用变量扩展。 @KindDragon 目前接受的答案没有使用延迟扩展,所以我认为@Srekel 指的是他自己的构造没有它就无法工作。
    • IIRC,在尝试实际使用 InstallDir 变量时出现了问题。如果没有延迟扩展,将它与传统的 % 查找一起使用是行不通的,因为它具有批处理文件开头的值 - 即什么都没有。
    【解决方案7】:

    嗯,vswhere.exe 并没有真正提供比 Visual Studio 版本安装路径更多的东西。这是我的 .profile 文件 Interix sn-p 从 2008 年开始做同样的小更新(shell 脚本):

    if [[ -n $PROCESSOR_ARCHITEW6432 || $PROCESSOR_ARCHITECTURE != "x86" ]]; then
      hkeybase='HKLM\SOFTWARE\Wow6432Node\Microsoft\'
    else
      hkeybase='HKLM\SOFTWARE\Microsoft\'
    fi
    for vsver in "15.0" "14.0" "12.0" "11.0" "10.0" "9.0" "8.0"; do
      _vsinstalldir=$(reg.exe query ${hkeybase}'VisualStudio\SxS\VS7' -v $vsver 2>/dev/null \
       | sed -n 's|.*REG_SZ *\([ [:print:]]*\).*|\1|p' | sed 's|\\|/|g')
    if [[ -n $_vsinstalldir ]]; then break; fi
    done; unset vsver
    

    这是枚举支持最新注册表项的 Visual Studio 安装

    HKLM\SOFTWARE\Microsoft\VisualStudio\SxS\VS7
    

    仍在为 Visual Studio 2017 工作。很容易转换为 cmd 语法。查询注册表更简单,并且在您的路径中不需要 vswhere.exe,因此对 IMO 有利。

    现在查找当前的 Visual C++ 实例和 SDK 完全是另一项任务。 :D

    常见的输出以防万一:

    C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/
    

    【讨论】:

      【解决方案8】:

      我花了很多时间试图修改 Srekel 的答案以仅搜索 VS2017。注意:如果您将下面的“for”语句放在“if”块中,它将破坏转义字符并且不起作用。

      SETLOCAL EnableDelayedExpansion
      
      if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
        echo "WARNING: You need VS 2017 version 15.2 or later (for vswhere.exe)"
      )
      
      set vswherestr=^"!ProgramFiles(x86)!\Microsoft Visual Studio\Installer\vswhere.exe^" -version [15.0,16.0^^) -products * -requires Microsoft.Component.MSBuild -property installationPath
      for /f "usebackq tokens=*" %%i in (`!vswherestr!`) do (  
        set BUILDVCTOOLS=%%i\Common7\Tools
        echo BUILDVCTOOLS: !BUILDVCTOOLS!
        if not exist !BUILDVCTOOLS!\VsDevCmd.bat (
          echo Error: Cannot find VS2017 Build Tools
          goto :buildfailed
        )
        call "!BUILDVCTOOLS!\VsDevCmd.bat"
      )    
      

      【讨论】:

        【解决方案9】:

        在此处查看以下答案:

        https://stackoverflow.com/a/55754831/2338477

        您可以使用任一命令行工具来查询 Visual Studio 位置,但我也提供了查询 Visual Studio 位置的编程方式。代码基于vswhere 源代码,但经过简化。

        【讨论】:

          【解决方案10】:

          我们只有 3 个 Visual Studio 版本。

          • \社区
          • \专业的
          • \企业

          因此,我们可以稍微简化一切。
          这里有一些经过测试的 CMD 脚本。

          @SET env_all_vs2017_root=%ProgramFiles(x86)%\Microsoft Visual Studio\2017
          @SET env_vs2017_path="%env_all_vs2017_root%\Professional"
          @IF NOT EXIST %env_vs2017_path%  SET env_vs2017_path="%env_all_vs2017_root%\Community"
          @IF NOT EXIST %env_vs2017_path%  SET env_vs2017_path="%env_all_vs2017_root%\Enterprise"
          @REM Let's fail laudly
          @IF NOT EXIST %env_vs2017_path%  SET "env_vs2017_path=Visual Studio 2017 install path was not found by %~nx0"
          
          @REM  You may want to remove quotes
          @SET unquoted=%env_vs2017_path:"=%
          
          
          @REM  And now let's see the result and PAUSE
          
          @ECHO VS 2017 install path is
          @ECHO %unquoted%
          
          @PAUSE
          

          【讨论】:

            猜你喜欢
            • 2011-09-28
            • 2010-09-07
            • 2011-08-23
            • 1970-01-01
            • 2016-09-10
            • 1970-01-01
            • 2023-04-11
            • 1970-01-01
            相关资源
            最近更新 更多