尽管 Windows 终端可以找到,但 VS Code 终端无法找到 AWS SAM

Dhr*_*ruv 3 windows powershell path-variables visual-studio-code aws-sam-cli

我通过适用于 Windows 的 AWS 的 msi 安装程序安装了 AWS SAM。运行安装程序后,我sam --version在cmd和powershell中运行。

PS C:\Users\dgupta> sam --version
SAM CLI, version 1.26.0
Run Code Online (Sandbox Code Playgroud)

它返回我刚刚安装的版本。然而,在 VS Code 中,我打开了一个终端并运行sam --version它,结果出现错误。

PS C:\Users\dgupta> sam --version
SAM CLI, version 1.26.0
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?VS Code 终端和普通终端不能访问相同的环境变量吗?

mkl*_*nt0 7

如果没有更多信息,就不可能诊断您的问题,但这些故障排除提示也许会有所帮助:

如果仅通过名称调用外部可执行文件( sam)失败,则问题必定是可执行文件所在的目录未在$env:PATH为当前进程定义的环境变量中列出。

但是,外部可执行文件的目录可能不在其中,并且这是一个同名的辅助PowerShell 命令sam$env:PATHsam,它知道 truesam的位置并在幕后调用它。例如,可以定义别名(例如New-Alias sam 'C:\path\to\sam.exe'-)或函数(例如-)。function sam { & C:\path\to\sam.exe $args }

从 PowerShell 会话中sam 可以找到:

  • 要确定名称在会话中引用的命令类型samCommandType,请使用以下命令并检查该列的值:
Get-Command sam
Run Code Online (Sandbox Code Playgroud)
  • 如果命令类型是Application,您确实正在处理外部可执行文件,并且Source列将报告其完整路径,您可以从中收集可执行文件的目录路径(您可以直接使用Split-Path (Get-Command -Type Application sam).Path

    • 然后,您需要诊断为什么该目录不在$env:PATH其他会话中 - 请参阅下面的第一部分
  • 如果命令类型不是 Application

    • 您需要确定辅助别名或函数的定义位置以及为什么其他会话看不到它,如果问题在新会话中可重现,则必须将其连接到哪些配置文件(如自动$PROFILE变量中所反映已加载

$env:PATH 诊断Windows 上缺少目录的原因:[1]

可能的原因:

  • 您刚刚安装了一个可执行文件,并且安装程序修改了注册表中的持久 $env:PATH定义。

    • 在此修改之前启动的任何正在运行的进程,甚至是之后直接从此类进程启动的进程(即作为子进程)都不会看到修改。

    • 解决方案:

      • 启动一个会话,在您的情况下意味着重新启动 Visual Studio Code,但请务必从“开始”菜单/任务栏/文件资源管理器启动它,因为它们知道修改后的环境。如有疑问,请注销并返回 Windows 会话,或重新启动计算机。

      • 或者,$env:PATH在会话中从注册表刷新 - 见下文。

  • 当前 PowerShell 会话中的某些内容(可能是无意中)sam从进程内$env:PATH变量中删除了 的目录。

    • 解决方案:

      • $env:PATH使用以下命令从注册表刷新进程内定义(请注意,任何先前的进程内修改都会丢失):
$env:PATH = 
  [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' +
  [Environment]::GetEnvironmentVariable('Path', 'User')
Run Code Online (Sandbox Code Playgroud)

如果这些解决方案没有帮助(持续),问题一定是:

  • 或者:即使持久 Path变量定义也缺少目录或兴趣的条目(即使安装程序通常会添加这样的条目)。

  • 或者:问题源自将哪些 PowerShell配置文件加载到不同的环境中。
    例如,如果给定的配置文件$env:PATH动态地将相关条目添加到每个会话,则不同的环境(例如 Visual Studio Code)可能无法加载相同的配置文件。

请参阅接下来的部分。


在 Windows 上Path,自行将目录条目添加到环境变量的持久定义中:[1]

  • 如果您不知道将哪个目录添加到Path变量中,可以通过如下命令找到它:

    # Find the directory/ies on drive C: that contain a "sam.exe" file.
    Get-ChildItem C:\ -Filter sam.exe -Recurse -File -ErrorAction Ignore | 
      ForEach-Object DirectoryName
    
    Run Code Online (Sandbox Code Playgroud)
  • 互动式

    • 运行sysdm.cpl,选择选项Advanced卡,然后单击,然后根据需要Environment Variables...修改变量:Path

      • 注意:要修改Path下的变量System variables,即系统范围的变量部分Path,您需要是管理员

      • 这样修改后Path,需要按照上述方式打开一个新的shell会话才能看到效果。

  • 以编程方式

    • 有关辅助功能,请参阅此答案Add-Path;答案还解释了为什么set.exe应该使用。

诊断所有平台上的会话中加载了哪些配置文件

PowerShell 的配置文件(默认情况下)在会话启动时加载(点源),并允许自定义会话,其中可以包括自定义别名定义、函数甚至进程内$env:PATH添加等内容。

多个配置文件,如果存在,所有这些文件都会沿着两个独立的维度加载(默认情况下):所有用户与当前用户,以及所有主机与当前主机(主机是 PowerShell 主机环境) ,例如常规控制台窗口或 Visual Studio Code 中的终端)。

自动变量$PROFILE报告当前用户、当前主机配置文件路径,但实际上具有列出所有路径的通常不可见的属性(您可以使用$PROFILE | select *- 请参阅此答案使它们可见)

给定用户将哪些配置文件加载到会话中由以下因素决定:

  • 从根本上来说,是否使用 CLI 的开关完全抑制-NoProfile配置文件加载。

  • 如果抑制(默认情况下,即使使用-Command-File调用):

    • 您正在使用的 PowerShell 版本:Windows 附带的旧版、仅限 Windows 的Windows PowerShell版本(其最新和最终版本为 5.1),其 CLI 为powershell.exe,与按需安装的跨平台PowerShell (核心)版本,其 CLI 为pwsh,具有单独的配置文件位置。

    • 主机环境的类型,反映在自动$Host变量中。

查看使用什么命令行来调用当前会话,请运行以下命令:

[Environment]::CommandLine
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 在 PIC(PowerShell 集成控制台)(在 Visual Studio Code 的集成终端中运行)中,您始终会看到-NoProfile参数,但配置文件仍可能在启动过程中加载 - 请参阅下文。

从上面可以看出,不同的主机环境会加载不同的配置文件集,而在PowerShell扩展附带的、在Visual Studio Code的集成终端中运行的PIC(PowerShell集成控制台)中,确实加载了不同的配置文件, IF 通过设置启用 - 与常规控制台窗口相比[2]PowerShell: Enable Profile Loading

如果您希望 PIC 会话加载与常规控制台窗口相同的当前用户配置文件:

  • 通过 Visual Studio Code 的设置,首先确保该PowerShell: Enable Profile Loading设置已启用,并根据需要启动新的 PIC 会话。

  • 从 PIC 会话中,运行psedit $PROFILE以打开特定于主机的当前用户配置文件以进行编辑。

  • 添加以下内容:

. ($PROFILE -replace '\.VSCode', '.PowerShell')
Run Code Online (Sandbox Code Playgroud)

[1] 请注意,类Unix平台没有用于定义持久环境变量的标准化机制,这就是 PowerShell 和 .NET 都没有为其提供 API 的原因。

[2] 请注意,即使没有PowerShell 扩展,您也可以在 Visual Studio Code 终端中使用 PowerShell作为通用 shell,并且此类会话确实使用与常规控制台窗口相同的配置文件 - 请参阅此答案