如何在Python中打开外部程序

14

重复编辑:不,我这样做了,但它不想启动Firefox。 我正在制作一个Cortana/Siri助手,当我说一些话时,我希望它可以打开一个Web浏览器。所以我已经完成了if部分,但我只需要它启动firefox.exe。我尝试了不同的方法,但出现了错误。以下是代码。请帮忙!它可以用记事本打开,但无法用Firefox打开。

#subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe']) opens the app and continues the script
#subprocess.call(['C:\Program Files\Mozilla Firefox\firefox.exe']) this opens it but doesnt continue the script

import os
import subprocess

print "Hello, I am Danbot.. If you are new ask for help!" #intro

prompt = ">"     #sets the bit that indicates to input to >

input = raw_input (prompt)      #sets whatever you say to the input so bot can proces

raw_input (prompt)     #makes an input


if input == "help": #if the input is that
 print "*****************************************************************" #says that
 print "I am only being created.. more feautrues coming soon!" #says that
 print "*****************************************************************" #says that
 print "What is your name talks about names" #says that
 print "Open (name of program) opens an application" #says that
 print "sometimes a command is ignored.. restart me then!"
 print "Also, once you type in a command, press enter a couple of times.."
 print "*****************************************************************" #says that

raw_input (prompt)     #makes an input

if input == "open notepad": #if the input is that
 print "opening notepad!!" #says that
 print os.system('notepad.exe') #starts notepad

if input == "open the internet": #if the input is that
 print "opening firefox!!" #says that
 subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe'])

3
请使用绝对路径指定 firefox.exe 的位置。 - fsp
1
记事本通常位于系统32文件夹下,该文件夹在PATH变量下,但火狐浏览器不太可能在此位置。 - YOU
你是什么意思?这是路径:C:\Program Files\Mozilla Firefox\firefox.exe。 - Dan
这个问题中的代码远远超过了提出明确问题所需的最低限度(实际上,这一点都不明确)。请参阅http://stackoverflow.com/help/mcve。 - Charles Duffy
1
至少要显示实际错误!它是否只是静默地无法打开浏览器窗口?它是否抛出异常?哪种异常?等等。如果您的错误与输入处理无关,则根本不需要显示输入处理周围的代码;请将这些部分删除。 - Charles Duffy
显示剩余4条评论
3个回答

34
简短的回答是os.system不知道在哪里找到firefox.exe
一种可能的解决方案是使用完整路径。建议使用subprocess模块:
import subprocess

subprocess.call(['C:\Program Files\Mozilla Firefox\\firefox.exe'])

注意在firefox.exe之前要加上\\!如果你使用\f,Python会将其解释为换页符:

>>> print('C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox
                                irefox.exe

当然,该路径不存在。 :-)

因此,要么转义反斜杠,要么使用原始字符串:

>>> print('C:\Program Files\Mozilla Firefox\\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe
>>> print(r'C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe

请注意,使用os.systemsubprocess.call将会阻止当前应用程序,直到启动的程序完成。因此,您可能希望使用subprocess.Popen代替。这将启动外部程序,然后继续脚本的执行。
subprocess.Popen(['C:\Program Files\Mozilla Firefox\\firefox.exe', '-new-tab'])

这将打开Firefox(或在运行的实例中创建一个新选项卡)。


更完整的示例是我通过github发布的open实用程序。该程序使用正则表达式将文件扩展名与要打开这些文件的程序匹配。然后,它使用subprocess.Popen在适当的程序中打开这些文件。为了参考,我在下面添加了当前版本的完整代码。

请注意,此程序是针对类UNIX操作系统编写的。在ms-windows上,您可能可以从注册表中获取文件类型的应用程序。

"""Opens the file(s) given on the command line in the appropriate program.
Some of the programs are X11 programs."""

from os.path import isdir, isfile
from re import search, IGNORECASE
from subprocess import Popen, check_output, CalledProcessError
from sys import argv
import argparse
import logging

__version__ = '1.3.0'

# You should adjust the programs called to suit your preferences.
filetypes = {
    '\.(pdf|epub)$': ['mupdf'],
    '\.html$': ['chrome', '--incognito'],
    '\.xcf$': ['gimp'],
    '\.e?ps$': ['gv'],
    '\.(jpe?g|png|gif|tiff?|p[abgp]m|svg)$': ['gpicview'],
    '\.(pax|cpio|zip|jar|ar|xar|rpm|7z)$': ['tar', 'tf'],
    '\.(tar\.|t)(z|gz|bz2?|xz)$': ['tar', 'tf'],
    '\.(mp4|mkv|avi|flv|mpg|movi?|m4v|webm)$': ['mpv']
}
othertypes = {'dir': ['rox'], 'txt': ['gvim', '--nofork']}


def main(argv):
    """Entry point for this script.

    Arguments:
        argv: command line arguments; list of strings.
    """
    if argv[0].endswith(('open', 'open.py')):
        del argv[0]
    opts = argparse.ArgumentParser(prog='open', description=__doc__)
    opts.add_argument('-v', '--version', action='version',
                      version=__version__)
    opts.add_argument('-a', '--application', help='application to use')
    opts.add_argument('--log', default='warning',
                      choices=['debug', 'info', 'warning', 'error'],
                      help="logging level (defaults to 'warning')")
    opts.add_argument("files", metavar='file', nargs='*',
                      help="one or more files to process")
    args = opts.parse_args(argv)
    logging.basicConfig(level=getattr(logging, args.log.upper(), None),
                        format='%(levelname)s: %(message)s')
    logging.info('command line arguments = {}'.format(argv))
    logging.info('parsed arguments = {}'.format(args))
    fail = "opening '{}' failed: {}"
    for nm in args.files:
        logging.info("Trying '{}'".format(nm))
        if not args.application:
            if isdir(nm):
                cmds = othertypes['dir'] + [nm]
            elif isfile(nm):
                cmds = matchfile(filetypes, othertypes, nm)
            else:
                cmds = None
        else:
            cmds = [args.application, nm]
        if not cmds:
            logging.warning("do not know how to open '{}'".format(nm))
            continue
        try:
            Popen(cmds)
        except OSError as e:
            logging.error(fail.format(nm, e))
    else:  # No files named
        if args.application:
            try:
                Popen([args.application])
            except OSError as e:
                logging.error(fail.format(args.application, e))


def matchfile(fdict, odict, fname):
    """For the given filename, returns the matching program. It uses the `file`
    utility commonly available on UNIX.

    Arguments:
        fdict: Handlers for files. A dictionary of regex:(commands)
            representing the file type and the action that is to be taken for
            opening one.
        odict: Handlers for other types. A dictionary of str:(arguments).
        fname: A string containing the name of the file to be opened.

    Returns: A list of commands for subprocess.Popen.
    """
    for k, v in fdict.items():
        if search(k, fname, IGNORECASE) is not None:
            return v + [fname]
    try:
        if b'text' in check_output(['file', fname]):
            return odict['txt'] + [fname]
    except CalledProcessError:
        logging.warning("the command 'file {}' failed.".format(fname))
        return None


if __name__ == '__main__':
    main(argv)

我把我的Firefox位置的路径复制了下来,然后按照subprocess代码进行操作,但是当我尝试从中启动Firefox时,它会显示:Traceback (most recent call last): File "Danbot.py", line 33, in <module> subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe']) File "c:\hp\bin\python\lib\subprocess.py", line 593, in init errread, errwrite) File "c:\hp\bin\python\lib\subprocess.py", line 793, in _execute_child startupinfo) WindowsError: [Error 22] 文件名、目录名或卷标语法不正确。 - Dan
@Dan 我猜这可能是因为Python会将\f解释为换页符的转义序列。请将\f改为\\f - Roland Smith
什么\f?我没有使用任何带有\f的东西。。? - Dan
1
是的。当Python读取'C:\Program Files\Mozilla Firefox\firefox.exe'时,它会解释\f并将其替换为一个换页符。因此,你得到了'C:\Program Files\Mozilla Firefox<formfeed>irefox.exe',这当然是不存在的。 :-) - Roland Smith
1
你需要在所有的斜杠上都加上双斜杠 \\,而不仅仅是最后一个... - birgersp
显示剩余2条评论

1

你可以像这样打开任何程序:

import subprocess

# This will pause the script until fortnite is closed
subprocess.call(['C:\Program Files\Fortnite\fortnite.exe'])

# But this will run fortnite and continue the script
subprocess.Popen(['C:\Program Files\Fortnite\fortnite.exe', '-new-tab'])

但是这里有一个方法可以找到任何程序的 .exe 文件(仅适用于 Windows)

我只知道如何在 Windows 中找到 .exe 文件

首先,点击 Windows 图标,然后输入任务管理器,打开它,然后找到 Fortnite,如果左侧有箭头,请单击它,如果还有另一个箭头,请再次单击。

请确保您按下底部的“更多详细信息”按钮。

然后向侧面滚动,直到找到顶部行上写有命令行,这里将显示每个正在运行的任务的 .exe 文件的路径

可能会出现 -(SOME_LETTER),但这些是选择运行 exe 文件时要执行的一些选项。对于每个 exe 文件,这些选项都不同

(小提示) 您可以按 Ctrl+Shift+Esc 打开任务管理器。 进入任务管理器,然后按选项(顶部),然后按始终置顶,这将使应用程序出现在所有内容的顶部,当应用程序崩溃并且您需要使用任务管理器关闭它时非常有用

谢谢。


0
如果你想在网上打开谷歌或其他网站,只需import webbrowser并打开URL。我会给你一个快速的例子。
import webbrowser

webbrowser.open("www.google.com")

3
这个问题不是关于在网络上打开某些东西(Firefox只是一个例子),也不是关于Python包具有某些外部程序功能。它是关于调用外部程序的问题,已经有了一个通用的答案。因此,这根本就不是一个答案。 - astentx

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