计算机找不到已安装的库

1 投票
2 回答
39 浏览
提问于 2025-04-14 15:27

我在使用VSCode的时候,每次安装一个Python库,都会收到这样的通知:

警告:脚本auto-py-to-exe.exe和autopytoexe.exe被安装在'C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts'这个位置,但这个位置不在PATH中。

不过我已经把这个位置加到PATH里了。如果我运行:

echo $env:PATH

我得到的结果是:

C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts:C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\PC\AppData\Local\Microsoft\WindowsApps;C:\Users\PC\AppData\Local\Programs\Microsoft VS Code\bin;C:\texlive\2023\bin\windows

这说明我确实把这个路径加上了。

我很困惑,因为我无法直接从命令行运行这些包,虽然导入它们是可以的。

我手动加过这个路径,也试过把它删掉,但都没用。有没有什么建议可以解决这个问题?

2 个回答

0

错误出在我指定的路径上。我一直以为大家都让我用冒号,但在@buran的建议下,我把在"${env:PATH}"前面的冒号改成了分号,这样就解决了问题。

旧路径:

 "PATH": "C:\\Users\\PC\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\Scripts:${env:PATH}"

新路径:

"PATH": "C:\\Users\\PC\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\Scripts;${env:PATH}"
1

你自己的解决方案在原则上是有效的——; 是 Windows 上需要的分隔符——但你的语句并不是有效的 PowerShell 代码,而且在 PowerShell 中,\ 字符不需要用 \\ 来转义;另外,你可以使用 LOCALAPPDATA 环境变量 更通用地表示新的目录路径;因此:

$newDir = "$env:LOCALAPPDATA\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts"
$env:PATH = "$newDir;$env:PATH" 

以上修改了 $env:PATH 仅对当前会话(进程)有效。
如果想要在 Windows 上持久化这个更改——让未来的会话也能看到这个更改,可以:

  • 交互式地,运行 sysdm.cpl,选择 高级 标签,然后点击 环境变量...,接着将 $newDir 的值添加到所需的范围;因为你的目录路径是用户特定的,所以要将其添加到 <用户名> 的用户变量 列表中。

  • 程序化地,这样做 surprisingly 难以稳健地实现:

    • 如果你不介意将原始的 REG_EXPAND_SZ 定义转换为静态的 REG_SZ 定义,你可以使用 [Environment]::SetEnvironmentVariable()(要针对机器级别的变量定义,将 'User' 改为 'Machine',但这样做需要提升权限(以管理员身份运行):

      [Environment]::SetEnvironmentVariable(
        'PATH',
        ($newDir + ';' + [Environment]::GetEnvironmentVariable('PATH', 'User')), 
        'User'
      ) 
      
    • 虽然这通常没有坏处,但可能会有;有关背景信息和稳健的替代方案,请参见 这个回答这个回答 将稳健的替代方案封装在一个辅助函数 Add-Path 中,并解释了为什么在更新 PATH 时应该避免使用 setx.exe

    • 一个更简单的程序化替代方案,也适用于类 Unix 平台,是将上述语句添加到你的 $PROFILE 文件中,但请注意,只有 PowerShell 会话和从中启动的程序才能看到更新后的 PATH,而且通过 -NoProfile CLI 参数启动 PowerShell 会话时可以抑制配置文件加载(PowerShell CLI(powershell.exe -NoProfile 适用于Windows PowerShellpwsh -NoProfile 适用于PowerShell (Core) 7+)

请注意,.NET 无法类 Unix 平台上提供持久化环境变量定义的 API,因为这些平台之间没有统一的机制。


跨平台PATH 环境变量背景信息

  • 在特殊的PATH 环境变量中存储的目录路径列表中使用的平台特定的分隔符是:

    • ;Windows
    • :类 Unix 平台上
  • 跨平台 脚本中,按如下方式在 PowerShell 中更改 PATH

    • 使用 $env:PATH - 全部大写 - 因为在 类 Unix 平台上,环境变量访问是区分大小写的,而这个特殊变量的名称确实是 PATH

      • Windows 上,官方名称是 Path,但由于环境变量访问不区分大小写,因此任何大小写变化,包括 PATH 都可以使用。
    • 使用名称令人困惑的 [System.IO.Path]::PathSeparator 属性来获取平台本地的分隔符。

    • 在形成要添加的目录路径时,使用平台本地的文件系统路径分隔符,.NET 在 [System.IO.Path]::DirectorySeparatorChar 属性中反映了这一点。

      • PowerShell 的 Join-Path 命令和 .NET 的 [System.IO.Path]::Combine() 方法在给定路径的组件时,会隐式使用平台本地的分隔符,Windows 上是 \,类 Unix 平台上是 /

        • 请注意,\ 在 PowerShell(以及 cmd.exe)中没有特殊含义,因此没有必要将字面\ 字符表示为 \\(不过,在文件系统路径的上下文中,这种意外重复的分隔符通常仍然被接受)。

      • Windows 上,你也可以使用 /,在 PATH 和 PowerShell 原生命令的上下文中都是安全的。

        • .NET 通过 [System.IO.Path]::AltDirectorySeparatorChar 属性反映了这一事实。

        • 然而,检查 $env:PATH现有条目的程序/脚本可能会假设使用 \,所以最好使用平台本地的分隔符。

        • 此外,一般来说,在某些 Windows 上下文中,/ 可用,例如在 cmd.exe 和 COM API 中。

    • 通常,尽量用环境 / 知名目录来表示你的目录路径,以便在添加条目时解析为字面路径:

      • 例如,路径中的 C:\Users\PC\AppData\Local 部分可以用环境变量 $env:LOCALAPPDATA 替代。

      • 但是,为了跨平台使用,最好使用平台无关的抽象,如 [System.Environment]::GetFolderPath() 提供的,尽管有一定限制。

        • 例如,上述内容的跨平台等价物是:

          [Environment]::GetFolderPath('LocalApplicationData')
          
      • 由于使用 [System.Environment]::GetFolderPath() 对 PowerShell 不太友好,GitHub 问题 #6966 请求通过一个单独的命名空间/提供程序,以平台无关的方式呈现已知文件夹,例如 $sf:LocalApplicationDatasf 代表特殊文件夹)。

撰写回答