【问题标题】:Installer: Cannot find python in path environment variable directly after installing it as 3rd party software安装程序:将 python 安装为 3rd 方软件后,无法直接在路径环境变量中找到 python
【发布时间】:2021-01-14 14:54:31
【问题描述】:

对于我的软件(仅适用于 Windows),我使用 NSIS 创建了一个安装程序。为了使软件正常工作,我将 python(版本 3.6.5)作为第 3 方软件(.exe 文件)提供。此外,我需要进行 pip 升级并安装一些模块(例如 NumPy)。

我对 NSIS 安装程序的方法如下:

  1. 运行可执行 python 安装程序:在我的安装程序中,提醒用户将 python 添加到环境 %path% 变量中。提取所有文件后,执行 python 的第 3 方安装程序。 Python 已安装并添加到 %path%。

  2. 运行小型 C++ 脚本 (PythonSetup.exe):(除其他外)该脚本使用来自 Windows.hGetEnvironmentVariable 匹配 python 目录的路径变量。如果 python 在路径中,那么它会执行一些命令,例如

python -m pip install --upgrade pip
python -m pip install numpy

否则它只会打印“python not found”和整个路径环境变量。

在 NSIS 中它是这样实现的(简化):

SetOutPath "$INSTDIR\python"
File "D:\python\python-3.6.5.exe"
ExecWait '"$INSTDIR\python\python-3.6.5.exe" InstallAllUsers=1 PrependPath=1'
Sleep 500
File "D:\python\PythonSetup.exe"
ExecWait '"$INSTDIR\python\PythonSetup.exe" $INSTDIR'
Sleep 500
SetOutPath "$INSTDIR"
Delete "$INSTDIR\python\python-3.6.5.exe"
Delete "$INSTDIR\python\PythonSetup.exe"
RmDir "$INSTDIR\python"

我的问题是

  • PythonSetup.exe 在 %path% 变量中找不到 python 目录。从Windows.h打印我使用GetEnvironmentVariable得到的路径,可以看到得到的路径确实不包含python目录。
  • 强制执行上面提到的命令我得到错误:'python.exe' is not recognized as an internal or external command, operable program or batch file.
  • 但是,在 Windows System Properties > Advanced > Environment Variables 中检查 %path% 变量表明 python 目录确实已添加到路径变量中。我在 PyhtonSetup.exe 的运行时检查了这一点,即在 NSIS 行 ExecWait '"$INSTDIR\python\PythonSetup.exe" $INSTDIR' 期间。
  • 在 NSIS 安装程序完成后立即执行 PythonSetup.exe 工作正常。

我试过了

  • 更长的Sleep
  • 其他 python 架构(32 位与 64 位)
  • 手动查找 python 目录并以这种方式调用python.exe,例如
C:\Program Files\python36-32\python.exe -m pip install numpy

有谁知道在PythonSetup.exeGetEnvironmentVariable返回的路径中为什么找不到python目录的原因,同时可以在系统属性中看到? 我觉得我可能遗漏了一些明显的东西......

【问题讨论】:

  • 你说的是 %path% 还是其他环境变量?
  • 是的,我说的是 %path%

标签: python c++ windows nsis


【解决方案1】:

当用户登录 Windows 时,会从注册表的用户和机器部分读取环境变量,并使用这些合并的变量启动初始过程。创建新进程时,它会继承其父进程的环境(除非您在启动进程时指定新的自定义环境)。

应用程序应该在更改环境时广播 WM_SETTINGCHANGE 消息,但实际上 Explorer 是唯一侦听此消息并动态更新其环境的应用程序。造成这种情况的主要原因是 Explorer 使用未记录的函数来执行此更新,而其他应用程序实现相同的功能是一个主要问题。

对于使用自定义变量的应用程序,很容易在安装程序中设置此值,以便它被启动的子进程继承:

System::Call 'KERNEL32::SetEnvironmentVariable(t "MYAPP_DIR", t "$InstDir")'

由于各种原因,以相同的方式更新 %PATH% 很棘手:

  • NSIS 有字符串长度限制,可能不适合较长的 %PATH%。
  • %PATH% 是来自 HKCU 和 HKLM 的值的组合,需要进行一些字符串操作才能正确连接它们。

我在安装程序中更新 %PATH% 的唯一建议是使用EnVar plug-in

EnVar::Update "" "PATH"
Pop $0 ; "0" on success

【讨论】:

  • 非常感谢,这正是我一直在寻找的!像魅力一样工作
猜你喜欢
  • 2020-01-03
  • 2022-10-07
  • 1970-01-01
  • 2023-03-29
  • 2019-04-24
  • 2020-08-18
  • 2018-11-03
  • 1970-01-01
  • 2018-02-20
相关资源
最近更新 更多