如何让 Visual Studio Developer Powershell 在 Visual Studio 代码的集成终端中工作?

How do I get Visual Studio Developer Powershell working in Visual Studio Code's integrated terminal?

我正在尝试为 Visual Studio 代码创建 Visual Studio 开发人员 Powershell 配置文件。这是我尝试过的:

"Developer Powershell": {
    "path": "pwsh",
    "args": [
        "-noe",
        "-c",
        "\"&{$vsPath = &(Join-Path ${env:ProgramFiles(x86)} '\Microsoft Visual Studio\Installer\vswhere.exe') -property installationpath; Import-Module (Join-Path $vsPath 'Common7\Tools\Microsoft.VisualStudio.DevShell.dll'); Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation}\""
    ],
    "icon": "terminal-powershell"
}

我复制并粘贴了我的 Windows 终端配置文件中的参数,它有效:

{
    "commandline": "pwsh.exe -noe -c \"&{$vsPath = &(Join-Path ${env:ProgramFiles(x86)} '\Microsoft Visual Studio\Installer\vswhere.exe') -property installationpath; Import-Module (Join-Path $vsPath 'Common7\Tools\Microsoft.VisualStudio.DevShell.dll'); Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation}\"",
    "icon": "C:\powershell\713\assets\Square44x44Logo.png",
    "name": "Developer PowerShell",
    "startingDirectory": "%USERPROFILE%",
}

但是,终端输出如下所示:

&{ = &(Join-Path C:\Program Files (x86) '\Microsoft Visual Studio\Installer\vswhere.exe') -property installationpath; Import-Module (Join-Path  'Common7\Tools\Microsoft.VisualStudio.DevShell.dll'); Enter-VsDevShell -VsInstallPath  -SkipAutomaticLocation}
  StaggoSTD   

注意:我在这里使用 Oh My Posh。这就是为什么没有书呆子字体的最后一行看起来很奇怪的原因。

那么如何使 Developer Powershell 正常工作?我尝试使用 powershell 而不是 pwsh 并删除转义的双引号,但没有任何作用。

tl;dr

以下 - 可用作 settings.json 文件的 "terminal.integrated.profiles.windows" 属性 内的 属性 以定义 终端profile named Developer PowerShell - 修复了您最初尝试的问题。

"Developer Powershell": {
  "path": "pwsh",
  "args": [
    "-noexit",
    "-c",
    "$vsPath = & \"${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe\" -property installationpath; Import-Module \"$vsPath/Common7/Tools/Microsoft.VisualStudio.DevShell.dll\"; Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation"
  ],
  "icon": "terminal-powershell"
}

注:

  • 鉴于环境变量 ProgramFiles(x86) 扩展到 C:\Program Files (x86) 的假设是相当安全的(尽管它 可能在异常配置的系统上扩展到不同的路径),,避免使用 ${env:ProgramFiles(x86)},通常应该工作得很好。

  • 上面的解决方案仍然使用 ${env:ProgramFiles(x86)},并通过将其包含在构造路径字符串 的嵌入式可扩展字符串 (\"...\") 中使其工作直接,而不是通过Join-Path。这不仅简化了命令,还避免了一个原始问题:在 (PowerShell) 字符串文字 之外使用 ${env:ProgramFiles(x86)} ;下一节将解释 为什么 这是一个问题。

  • 另一个简化是使用 / 作为路径分隔符 - PowerShell 可以与 \ 互换 - 这不需要在 内转义JSON 字符串.


背景资料:

  • 由于 您将 PowerShell CLI 参数作为 数组 传递,通过 "args" 属性 ,您应该 而不是 将传递给 -c 参数的字符串另外包含在 嵌入、转义 "..." 字符串(\"...\"),因为使用 "args"Visual Studio 代码 在将最终调用的命令行拼接在一起时执行任何必要的转义场景。

    • 如果您确实在 \"...\" 中使用了 enclosure,PowerShell 最终会将您的命令视为单个命令,expandable string literal,其扩展值被隐式回显 - 这就是您看到的症状;简单来说,PowerShell 最终执行了类似 "$vsPath = ..." 的操作,它试图扩展(插入)变量 $vsPath,并且由于不存在这样的变量,它的计算结果为 空字符串 ,导致输出以下逐字字符串: = ...

    • 换句话说:使用"args",你不必担心在命令行中引用:你简单地制定每个参数应该 逐字 ,然后让 VS Code 进行转义 - 然而,JSON 相关的转义你 do 需要执行 ,而且 VS Code 的陷阱而不是 PowerShell 潜在 up-front 扩展变量引用 例如${env:ProgramFiles(x86)}:

      • JSON-escaping: 转义嵌入" as \", \ as \;请注意,后者的痛苦可以通过使用 / 作为路径分隔符来缓解,PowerShell 可以与 \.
      • 互换接受
      • VS Code 前期变量扩展陷阱
        • VS Code 仅考虑 ${someName}${someNameSpace:someName} 形式的引用以进行前期扩展 - 不包括 $someName$someNameSpace:someName
        • 因此,$vsPath$env:USERNAME 等典型的 PowerShell 变量引用 不会 受到潜在的前期扩展的影响,但它 可能 发生在 {...} 中的封装在 PowerShell 中语法 需要 的情况下,由于 非标准名称 这样的作为 ${env:ProgramFiles(x86)}.
        • 使用 env: 命名空间,具体而言,前期扩展 总是 发生(与 command:config:input:,但这些通常不会在 PowerShell 中定义):VS Code 将 ${env:ProgramFiles(x86)} 等引用扩展为 逐字值 该环境变量。也就是说,${env:ProgramFiles(x86)} 在命令字符串 之前被逐字替换为 C:\Program Files (x86),然后 PowerShell 看到该字符串,并且 缺少引号 围绕该值然后导致 语法错误 .
        • 虽然无法抑制这种前期扩展一个简单的解决方案是将引用 用引号括起来 : '${env:ProgramFiles(x86)}'\"${env:ProgramFiles(x86)}\"。请注意,这假设值本身分别不包含 '";如果无法做出此假设,请使用以下解决方法:
          (Get-Content 'env:ProgramFiles(x86)')
  • 顺便说一句:没有必要在 & { ... } 中包含传递给 -c (-Command) 的语句 - 只需使用 ...(语句)直接。

    • 旧版本的 CLI documentation 错误地建议 & { ... } 是必需的,但这已被更正。

我想通了。首先,我要感谢mklement0,他提交了一个关于简化论点的答案,但是已经被删除了。使用它,我将 ${env:ProgramFiles(x86)} 替换为 'C:\Program Files (x86)' 并且一切顺利。为了检查是否一切正常,我 运行 gcm fsi 告诉我 F# Interative 在那里,即使它不在我的正常 PATH 上。这是我现在的个人资料,供任何想要在 VSCode:

中使用 Developer Powershell 的人使用
"Developer Powershell": {
    "path": "pwsh",
    "args": [
        "-noe",
        "-c",
        "$vsPath = &(Join-Path 'C:\Program Files (x86)' '\Microsoft Visual Studio\Installer\vswhere.exe') -property installationpath; Import-Module (Join-Path $vsPath 'Common7\Tools\Microsoft.VisualStudio.DevShell.dll'); Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation"
    ],
    "icon": "terminal-powershell"
}

至于为什么会有环境变量,我是从a Microsoft blog复制粘贴的。因为它适用于 Windows 终端,所以我认为它也适用于 VSCode。但是,在我查找 Developer Powershell 配置文件的所有其他地方,都没有使用环境变量。后来,我发现我可以从 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools.

的快捷方式复制