单个cmd.exe会话的临时文件关联

10

我需要设置.py文件的关联,使其与特定的Python版本一起执行。但我只需要在单个cmd.exe会话中进行此关联(并行会话不应受影响)。Windows允许这样做吗?

我怀疑答案是否定的,但在放弃将此功能纳入virtualenv之前,我想看到一些证据。


简单的解决方案是在命令行中指定要使用的Python版本,而不是依赖于文件关联,因为后者并不适用于此。 - David Heffernan
我已经有几个名为python32、python27等的Python解释器。我想要的是在这个虚拟环境会话中避免在命令行中指定解释器。 - anatoly techtonik
4个回答

9
当然可以。你在Jakob的回答中已经非常接近答案了 -
如果使用环境变量更改文件关联是可能的 - 这会有所帮助,但似乎不可能。
这是可能的。您需要做的就是使用REG_EXPAND_SZ类型的注册表键和键值中的环境变量。例如,将
%python_home%\python %1 %*
作为
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command
键的(Default)值,并将其设置为REG_EXPAND_SZ,就可以定义打开Python文件时要使用哪个版本的Python。您可以通过设置python_home环境变量来决定使用哪个Python版本,并且您当然可以在每个命令行会话中执行此操作。请参阅我对问题where in the registry does Windows store, with which program to open certain file types?的回答。

说到这一点,现在有一个专门解决这个问题的工具,我强烈推荐。它叫做pylauncher。从文档中可以看到:

PEP 397兼容的Windows下Python启动器。请参阅http://www.python.org/dev/peps/pep-0397/获取PEP, http://www.red-dove.com/screencasts/launcher/launcher.html获取屏幕录像

如果将其添加到PATHEXT环境变量中,甚至可以跳过.py扩展名。请参见问题What environment variables will be used when calling an EXE from command line?


2
这很有效。我认为按照这种方式设置环境很重要,否则你可能会通过调用错误的解释器Python实例而不被注意到,从而得出错误的结论。我的做法是:
  • 设置一个空的虚拟环境ENV
  • 使VIRTUAL_ENV系统环境变量指向它
  • 基于VIRTUAL_ENV更改关联,使其相对路径 reg add HKEY_CLASSES_ROOT\Python.File\shell\open\command /ve /t REG_EXPAND_SZ /d "\"%VIRTUAL_ENV%\Scripts\python.exe\" \"%1\" %*"
  • 激活环境会改变VIRTUAL_ENV的值
- xverges
然而,如果不必创建这个虚拟环境virtualenv,那就太好了。一定有什么方法... - Piotr Dobrogost
很不幸,我的Windows电脑坏了,我无法检查这是否可行,但它看起来是可行的。 - anatoly techtonik

3
在Windows中,您可以使用assocftype命令从命令行更改文件关联(您可以从此处下载Windows命令参考 PDF文件)。
您可以使用assoc命令查看当前与.py文件关联的文件类型:
> assoc .py
.py=Python.File

有了这些信息,您可以使用ftype命令检查当前与Python.File文件类型相关联的程序:

> ftype Python.File
Python.File="C:\Python2.6\python.exe" "%1" %*

您可以使用 ftype更改关联的程序:
> ftype Python.File="C:\Python2.7\python.exe" "%1" %*
Python.File="C:\Python2.7\python.exe" "%1" %*

这样设置的关联是持久的,因为它们存储在Windows注册表中。这意味着您需要在终止cmd.exe会话之前设置或恢复它到您想要的状态。我建议您使用一个或多个批处理文件来实现此目的。 cmd.exe本身接受一个/k参数,您可以使用它来在启动时执行一个批处理文件,以设置您最初想要的文件关联。然后,您还可以提供一个自定义的quit.bat,在退出cmd会话之前恢复关联。

1
只是一句话:assocftype 都作用于 HKEY_LOCAL_MACHINE\Software\Classes 中的键,如果存在,则被 HKEY_CURRENT_USER\Software\Classes 中的条目覆盖。 - Piotr Dobrogost
@martineau:这一点很清楚。问题在于,如果没有REG_EXPAND_SZ,关联就无法起作用,所以问题是ftype Python.File="%PYTHON_HOME%\python.exe" "%1" %*是否有效? - anatoly techtonik
1
@techtonik:如果您分两步执行,它将起作用。先执行“set TMP_HOME=PYTHON_HOME”,然后执行“ftype Python.File="%%TMP_HOME%%\python.exe" "%1" %*”。 - martineau
如果我能从批处理文件中以某种方式访问全局PYTHON_HOME,那么这可能是解决方案。否则,当覆盖系统Python时,我会冒着破坏系统Python的风险。 - anatoly techtonik
我是说如果之前没有设置全局PYTHON_HOME,那么我需要将其设置为以前的版本ftype Python.File="%PYTHON_HOME%\python.exe" "%1" %* - anatoly techtonik
显示剩余9条评论

1

你最好的选择可能是在脚本中设置 PATH 变量,并通过编写 python script.py 来调用 python。文件关联是全局的,共享于进程之间。环境变量是处理本地的,这就是为什么我建议使用这个解决方案的原因。


路径已经设置为所需。我想避免每次都输入Python。 - anatoly techtonik
文件关联是全局的,并且在进程之间共享。 - David Heffernan
那么,您确认没有办法在单个cmd.exe会话中运行script.py而不将解释器放入PATH并作为python script.py运行脚本吗? - anatoly techtonik
由于关联是在进程之间共享的,所以你不能那样做。 - David Heffernan

0

您可以使用Windows的set命令来设置临时关联,该设置将持续到shell结束,除非将其附加到系统环境变量。


1
如果这是真的,请在您的回答中添加一个例子。 - martineau
1
set 命令用于更改环境变量,而问题询问的是文件关联,这是完全不同的事情。 - David Heffernan
如果可以使用环境变量更改文件关联,那将会很有帮助,但似乎不可能。 - anatoly techtonik
@techtonik 可以的。请看我的回答。 - Piotr Dobrogost
@David Heffernan 这些是不同的东西,但希望它们可以一起工作,实现 OP 所要求的 :) - Piotr Dobrogost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接