小编典典

从Python启动另一个程序>分别地<

python

我正在尝试从Python运行外部单独的程序。通常,这不会有问题,但是该程序是一个游戏,并且内置了Python解释器。当我使用subprocess.Popen时,它会启动单独的程序,但是会在原始程序的Python实例下启动它,以便它们共享第一个Python控制台。我可以很好地结束第一个程序,但是我宁愿有单独的控制台(主要是因为我隐藏了控制台启动功能,但是当我使用subprocess.POpen从Python启动程序时,它会显示出来)。

如果我可以完全独立地启动第二个程序,就好象我只是“双击它”一样,我就想这样做。另外,由于我的目标是跨平台兼容性,所以os.system也不起作用,并且仅在Windows上可用。


阅读 157

收藏
2020-12-20

共1个答案

小编典典

如果我可以完全独立地启动第二个程序,就像我只是“双击它”一样,我会很喜欢。

从2.7和3.3开始,Python没有跨平台的方法来做到这一点。shutil.open将来可能会添加新方法(可能不在该名称下);有关详细信息,请参见http://bugs.python.org/issue3177。但是在那之前,您必须为自己关心的每个平台编写自己的代码。

幸运的是,与shutil.open最终希望提供的内容相比,您要尝试的操作更简单,更通用,这意味着编写代码并不难:

  • 在OS X上,有一个名为的命令open可以完全满足您的要求:“打开命令会打开一个文件(或目录或URL),就像您双击该文件的图标一样。” 因此,您可以popen open /Applications/MyGame.app
  • 在Windows上,等效命令为start,但不幸的是,它是cmd.exe外壳程序的一部分,而不是独立程序。幸运的是,Python附带了一个os.startfile执行相同功能的函数,因此而已os.startfile(r'C:\Program Files\MyGame\MyGame.exe')
  • 在与FreeDesktop兼容的* nix系统(包括大多数现代linux发行版等)上,有一个非常相似的命令,称为xdg-open:“ xdg-open在用户首选的应用程序中打开文件或URL。” 再次,只是popen xdg-open /usr/local/bin/mygame
  • 如果希望在其他平台上运行,则需要做一些研究才能找到最佳的同类产品。否则,对于Mac和Windows以外的任何产品,我都将尝试尝试popen xdg-open,如果失败,则抛出错误。

有关(未试用的)示例,请参见http://pastebin.com/XVp46f7X

请注意,这只能运行实际上可以双击以在Finder / Explorer / Nautilus / etc中启动的内容。例如,如果您尝试启动“
./script.py”,具体取决于您的设置,它可能会启动一个带有脚本的文本编辑器。

另外,在OS
X上,您要运行.app软件包,而不是其中的UNIX可执行文件。(在某些情况下,启动UNIX可执行文件(无论是在.app捆绑包中还是独立运行)都可以,但不要指望它。)

另外,请记住,以这种方式启动程序与从命令行运行该程序不同,尤其是它将从Windows / Launch Services / GNOME / KDE
/继承其环境,当前目录/驱动器等。等等 会话,而不是您的终端会话。如果您需要更多的控制孩子的过程,你需要看的文件openxdg- open以及os.startfile和/或想出不同的解决方案。

最后,只是因为open/ xdg- open/os.startfile成功,实际上并不意味着游戏启动正常。例如,如果启动后崩溃甚至无法创建窗口,那么对您来说仍然看起来像成功。

您可能需要查看PyPI来查找所需功能的库。http://pypi.python.org/pypi/desktop看起来很可能。

或者,您可以浏览3177期中的补丁,然后选择最喜欢的补丁。据我所知,它们都是纯Python,您可以轻松地将添加的函数放在自己的模块中,而不是inos或中shutil

作为一种快速技巧,您可能可以(滥用)webbrowser.open。“请注意,在某些平台上,尝试使用此功能打开文件名可能会起作用并启动操作系统的关联程序。但是,这既不受支持,也无法移植。”
特别是IIRC,它将无法在OS X 10.5+上运行。但是,我认为创建文件:文件名之外的URL实际上 确实可以 可在OS
X和Windows上运行,并且对于大多数(但不是全部)配置也可在Linux上运行。如果是这样,对于快速而肮脏的脚本来说可能就足够了。请记住,它尚未被记录为可工作的,它可能会破坏您的某些用户,它可能会在将来破坏,并且它被Python开发人员明确认为是滥用,因此我不会指望它做任何更严重的事情。与上面更正确的方法一样,启动’script.py’或’Foo.app/Contents/MacOS/foo’,传递env变量等也会遇到相同的问题。

您的问题中几乎所有其他内容都是不相关和错误的:

通常,这不会有问题,但是该程序是一个游戏,并且内置了Python解释器。

没关系 如果游戏正在从C代码写入stdout,它将做完全相同的事情。

当我使用subprocess.Popen时,它会启动单独的程序,但是会在原始程序的Python实例下启动

不,不是。它启动了一个全新的过程,其嵌入式Python解释器是Python的全新实例。您可以通过运行与游戏嵌入版本不同的Python进行验证。

以便他们共享第一个Python控制台。

不,他们没有。他们可能共享相同的tty / cmd窗口,但这不是一回事。

我可以很好地结束第一个程序,但是我宁愿有单独的控制台(主要是因为我隐藏了控制台启动功能,但是当我使用subprocess.POpen从Python启动程序时,它会显示出来)。

您始终可以通过管道将子级的stdout和stderr传送到例如日志文件,然后可以将其与父进程的输出分开查看(如果需要)。但是我认为这与您真正关心的事情无关。

另外,由于我的目标是跨平台兼容性,所以os.system也不起作用,并且仅在Windows上可用。

错误; os.system可在“
Unix,Windows”上使用-
可能在您关心的任何地方。但是,它不起作用,因为它使用相同的tty在脚本的子外壳中运行子程序。(这还有很多其他问题,例如阻塞直到孩子完成。)

2020-12-20