当 $env:path 中定义了多个可执行文件时,windows 如何决定使用哪个 python 可执行文件?
How does windows decide which python executable to use when multiple are defined in $env:path?
我有几个 python 可执行文件可从默认的 powershell 提示符中获得,如 where.exe python
:
C:\Program Files\Inkscape\bin\python.exe
C:\Users1479\AppData\Local\Programs\Python\Python310\python.exe
C:\Users1479\AppData\Local\Microsoft\WindowsApps\python.exe
当我从这个 powershell 提示启动 python 解释器时,它使用第一个可执行文件:
>>>python
Python 3.9.7 (default, Sep 22 2021, 08:12:47) [GCC 10.3.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'C:\Program Files\Inkscape\lib\python39.zip', 'C:\Program Files\Inkscape\lib\python3.9', 'C:\Program Files\Inkscape\lib\python3.9\lib-dynload', 'C:\Users\921479', 'C:\Program Files\Inkscape\lib\python3.9\site-packages']
我不想从我的 windows 路径环境变量中删除 C:\Program Files\Inkscape\bin
,因为我将 inkscape
命令行工具用于其他目的。但是,我更希望 powershell 使用 python 3.10 的本地安装作为我的“默认”python 解释器。
当我检查 $env:path
变量时,Inkscape 文件夹似乎是在 python 3.10 文件夹之后定义的。所以它看起来像其他东西被用来解析 python 可执行文件:
>>>$env:path
C:\Python310\Scripts\;C:\Python310\;C:\Python39\Scripts\;C:\Python39\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\ProgramData\chocolatey\bin;C:\Users1479\AppData\Local\SumatraPDF;C:\Program Files\Git\cmd;C:\texlive21\bin\win32;C:\Program Files (x86)\PDFtk Server\bin\;C:\Program Files (x86)\Lua.1;C:\Program Files (x86)\Lua.1\clibs;C:\Program Files\Inkscape\bin;C:\Program Files\dotnet\;C:\Users1479\AppData\Local\Programs\Python\Python310\Scripts\;C:\Users1479\AppData\Local\Programs\Python\Python310\;C:\Users1479\AppData\Local\Microsoft\WindowsApps;C:\Users1479\.dotnet\tools
powershell/windows 如何决定使用哪个 python
可执行文件?我该如何修改它?
Windows 将执行什么并不重要,因为它可能取决于所使用的 API。
其中之一是CreateProcessW:
- The directory from which the application loaded.
- The current directory for the parent process.
- The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
自 Windows Vista 起,环境变量 %NoDefaultCurrentDirectoryInExePath% 配置是否应搜索当前目录(来源:MSDN)。
此外:如果您 运行 python
没有扩展名,环境变量 %PathExt% 用于查找可执行扩展名。 (来源:MSDN)。
The default value for the PATHEXT variable is: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
解决此类问题的好工具是 SysInternals Process Monitor。为“路径包含 python”(而不是 python.exe)设置过滤器,您将看到准确的搜索顺序。对于不包含 Python 可执行文件的目录,它将报告“没有这样的文件”。
另请注意:search order for DLLs 可能不同。
提供了很好的一般信息。
至于在 中使用 直接调用 可执行文件 仅按名称 (包括或不包括其文件扩展名) PowerShell:
只在 $env:Path
中列出的目录中查找按名称指定的可执行文件,按顺序 和可执行文件使用 第一个 匹配目录。
请注意,PowerShell - 与 cmd.exe
不同 - 按照设计,作为一项安全功能,不会 执行位于 current 仅按名称目录,并要求您通过在名称前加上 .\
(或使用完整路径)来明确调用此类程序的意图。
换句话说:如果 python.exe
可执行文件恰好出现在 当前 目录中,提交 python
:
- 在
cmd.exe
中会执行it,
- 而 PowerShell 会 忽略它 并仅参考
$env:PATH
。
这 与您的经验一致:即使您的 $env:Path
变量在 C:\Program Files\Inkscape\bin
之前有 C:\Python310\
和 C:\Python39\
的条目=],这些 不 包含 python.exe
可执行文件,正如您的 where.exe
命令输出所暗示的那样,这表明唯一相关的目录是 C:\Program Files\Inkscape\bin
,
C:\Users1479\AppData\Local\Programs\Python\Python310
,以及
C:\Users1479\AppData\Local\Microsoft\WindowsApps
, 反映在您的 $env:Path
值中的顺序。
您在 PowerShell 中的 where.exe
调用的 等价物是(除了 PowerShell 从不在 current 中列出任何匹配项目录),使用 Get-Command
cmdlet:
Get-Command python -All
省略 -All
将仅显示命令的 有效 形式,即调用时实际使用的形式。
How can I modify this?
再次从 PowerShell 视角:
根据您的需要,您有两种选择:
您可以选择性地修改$env:PATH
仅用于当前 PowerShell 会话,这将将修改的查找顺序限制为那个会话和从它启动的进程。独立进程(例如单独的 cmd.exe
会话)不会 受到影响:
# Simply *prepend* the desired directory to $env:Path
$env:Path = 'C:\Users1479\AppData\Local\Programs\Python\Python310;' + $env:Path
如果您想将修改后的查找顺序限制为仅 PowerShell 代码 - 即 python
和 python.exe
调用以 交互方式 或从 PowerShell 脚本或函数 提交 - 您可以 定义 aliases.
New-Alias python.exe C:\Users1479\AppData\Local\Programs\Python\Python310\python.exe
New-Alias python python.exe
在这两种情况下,如果您想为所有未来的 PowerShell 会话自动实施这些修改,请将语句添加到您的 $PROFILE
file。
我有几个 python 可执行文件可从默认的 powershell 提示符中获得,如 where.exe python
:
C:\Program Files\Inkscape\bin\python.exe
C:\Users1479\AppData\Local\Programs\Python\Python310\python.exe
C:\Users1479\AppData\Local\Microsoft\WindowsApps\python.exe
当我从这个 powershell 提示启动 python 解释器时,它使用第一个可执行文件:
>>>python
Python 3.9.7 (default, Sep 22 2021, 08:12:47) [GCC 10.3.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'C:\Program Files\Inkscape\lib\python39.zip', 'C:\Program Files\Inkscape\lib\python3.9', 'C:\Program Files\Inkscape\lib\python3.9\lib-dynload', 'C:\Users\921479', 'C:\Program Files\Inkscape\lib\python3.9\site-packages']
我不想从我的 windows 路径环境变量中删除 C:\Program Files\Inkscape\bin
,因为我将 inkscape
命令行工具用于其他目的。但是,我更希望 powershell 使用 python 3.10 的本地安装作为我的“默认”python 解释器。
当我检查 $env:path
变量时,Inkscape 文件夹似乎是在 python 3.10 文件夹之后定义的。所以它看起来像其他东西被用来解析 python 可执行文件:
>>>$env:path
C:\Python310\Scripts\;C:\Python310\;C:\Python39\Scripts\;C:\Python39\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\ProgramData\chocolatey\bin;C:\Users1479\AppData\Local\SumatraPDF;C:\Program Files\Git\cmd;C:\texlive21\bin\win32;C:\Program Files (x86)\PDFtk Server\bin\;C:\Program Files (x86)\Lua.1;C:\Program Files (x86)\Lua.1\clibs;C:\Program Files\Inkscape\bin;C:\Program Files\dotnet\;C:\Users1479\AppData\Local\Programs\Python\Python310\Scripts\;C:\Users1479\AppData\Local\Programs\Python\Python310\;C:\Users1479\AppData\Local\Microsoft\WindowsApps;C:\Users1479\.dotnet\tools
powershell/windows 如何决定使用哪个 python
可执行文件?我该如何修改它?
Windows 将执行什么并不重要,因为它可能取决于所使用的 API。
其中之一是CreateProcessW:
- The directory from which the application loaded.
- The current directory for the parent process.
- The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
自 Windows Vista 起,环境变量 %NoDefaultCurrentDirectoryInExePath% 配置是否应搜索当前目录(来源:MSDN)。
此外:如果您 运行 python
没有扩展名,环境变量 %PathExt% 用于查找可执行扩展名。 (来源:MSDN)。
The default value for the PATHEXT variable is: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
解决此类问题的好工具是 SysInternals Process Monitor。为“路径包含 python”(而不是 python.exe)设置过滤器,您将看到准确的搜索顺序。对于不包含 Python 可执行文件的目录,它将报告“没有这样的文件”。
另请注意:search order for DLLs 可能不同。
至于在 中使用 直接调用 可执行文件 仅按名称 (包括或不包括其文件扩展名) PowerShell:
只在
$env:Path
中列出的目录中查找按名称指定的可执行文件,按顺序 和可执行文件使用 第一个 匹配目录。请注意,PowerShell - 与
cmd.exe
不同 - 按照设计,作为一项安全功能,不会 执行位于 current 仅按名称目录,并要求您通过在名称前加上.\
(或使用完整路径)来明确调用此类程序的意图。换句话说:如果
python.exe
可执行文件恰好出现在 当前 目录中,提交python
:- 在
cmd.exe
中会执行it, - 而 PowerShell 会 忽略它 并仅参考
$env:PATH
。
- 在
这 与您的经验一致:即使您的 $env:Path
变量在 C:\Program Files\Inkscape\bin
之前有 C:\Python310\
和 C:\Python39\
的条目=],这些 不 包含 python.exe
可执行文件,正如您的 where.exe
命令输出所暗示的那样,这表明唯一相关的目录是 C:\Program Files\Inkscape\bin
,
C:\Users1479\AppData\Local\Programs\Python\Python310
,以及
C:\Users1479\AppData\Local\Microsoft\WindowsApps
, 反映在您的 $env:Path
值中的顺序。
您在 PowerShell 中的 where.exe
调用的 等价物是(除了 PowerShell 从不在 current 中列出任何匹配项目录),使用 Get-Command
cmdlet:
Get-Command python -All
省略 -All
将仅显示命令的 有效 形式,即调用时实际使用的形式。
How can I modify this?
再次从 PowerShell 视角: 根据您的需要,您有两种选择:
您可以选择性地修改
$env:PATH
仅用于当前 PowerShell 会话,这将将修改的查找顺序限制为那个会话和从它启动的进程。独立进程(例如单独的cmd.exe
会话)不会 受到影响:# Simply *prepend* the desired directory to $env:Path $env:Path = 'C:\Users1479\AppData\Local\Programs\Python\Python310;' + $env:Path
如果您想将修改后的查找顺序限制为仅 PowerShell 代码 - 即
python
和python.exe
调用以 交互方式 或从 PowerShell 脚本或函数 提交 - 您可以 定义 aliases.New-Alias python.exe C:\Users1479\AppData\Local\Programs\Python\Python310\python.exe New-Alias python python.exe
在这两种情况下,如果您想为所有未来的 PowerShell 会话自动实施这些修改,请将语句添加到您的 $PROFILE
file。