在维护CLI实用程序的过程中,我想添加一个update
操作,该操作将从PyPI获取该软件包的最新版本并升级现有安装。
$ cli -V
1.0.23
$ cli update
// many lines of pip spam
$ cli -V
1.0.24 // or etc
这适用于所有在系统范围内安装了Python的机器(在C:\Python36
或类似版本中),但是作为用户安装Python的机器(在C:\users\username\AppData\Local\Programs\Python\Python36
中)在卸载旧版本时会收到此错误:
Could not install packages due to an EnvironmentError: [WinError 5] Access is denied: 'C:\\Users\\username\\AppData\\Local\\Temp\\pip-uninstall-f5a7rk2y\\cli.exe'
Consider using the `--user` option or check the permissions.
我原以为这是因为当pip试图删除它时,错误文本中出现的cli.exe
当前正在运行,但是这里的路径不是qzxswpoi那个exe所在的地方,而是%LOCALAPPDATA%\Programs\Python\Python36\Scripts
。如何将文件移动到那里,但一旦它在那里就不能删除它?
如错误消息所推荐的那样在安装args中包含%TEMP%
(与此问题的早期编辑的指示相反)解决了问题,但将--user
可执行文件移动到其他位置。
我希望得到一个答案:
cli
添加到args。虽然问题相当普遍,但MCVE如下:
--user
正如最初推测的那样,这里的问题是试图删除正在运行的可执行文件。 Windows不是那种废话的粉丝,当你尝试时抛出def update(piphost):
args = ['pip', 'install',
'--index-url', piphost,
'-U', 'cli']
subprocess.check_call(args)
update('https://mypypiserver:8001')
。奇怪的是,你肯定可以重命名正在运行的可执行文件,实际上有几个PermissionErrors
questions from different使用这个事实来允许对正在运行的可执行文件进行明显的更改。
这也解释了为什么可执行文件似乎从tags运行但未能从%LOCALAPPDATA%\Programs\Python\Python36\Scripts
删除。它在执行期间已被重命名(移动)到%TEMP%
文件夹(这是合法的),然后pip尝试删除该目录,同时删除该文件(这是非法的)。
实现如下:
%TEMP%
)Path(sys.argv[0]).with_suffix('.exe')
更新包pip install