【问题标题】:How do I close a file opened using os.startfile(), Python 3.6如何关闭使用 os.startfile()、Python 3.6 打开的文件
【发布时间】:2020-01-14 11:56:25
【问题描述】:

我想关闭一些我使用 os.startfile() 打开的文件,例如 .txt、.csv、.xlsx。

我知道之前有人问过这个问题,但我没有找到任何有用的脚本。

我使用的是 windows 10 环境

【问题讨论】:

  • os.startfile() 不会导致关联的应用程序启动并打开文件吗?因此,您不会在脚本中获取文件指针,因为您的脚本根本无法打开文件-->您无法关闭它。您必须关闭前面提到的应用程序(或通过此应用程序关闭文件)。
  • @Jobomat,感谢您的回复,我在变量中有文件路径,用于打开文件。我只是想关闭它,在这种情况下运气好,我只是不想手动操作

标签: python python-3.x file python-os


【解决方案1】:

我认为问题的措辞有点误导 - 实际上你想关闭你用os.startfile(file_name)打开的应用程序

不幸的是,os.startfile 没有为您提供返回进程的任何句柄。 help(os.startfile)

启动相关应用程序后,startfile 立即返回。 没有选项等待应用关闭,也没有办法 检索应用程序的退出状态。

幸运的是,您还有另一种通过 shell 打开文件的方法:

shell_process = subprocess.Popen([file_name],shell=True) 
print(shell_process.pid)

返回的 pid 是父 shell 的 pid,而不是您的进程本身的 pid。 杀死它是不够的——它只会杀死一个 shell,而不是子进程。 我们需要找到孩子:

parent = psutil.Process(shell_process.pid)
children = parent.children(recursive=True)
print(children)
child_pid = children[0].pid
print(child_pid)

这是您要关闭的 pid。 现在我们可以终止进程了:

os.kill(child_pid, signal.SIGTERM)
# or
subprocess.check_output("Taskkill /PID %d /F" % child_pid)

请注意,这在 Windows 上有点复杂 - 没有 os.killpg 更多信息:How to terminate a python subprocess launched with shell=True

另外,当我尝试使用os.kill 终止 shell 进程时,我收到了PermissionError: [WinError 5] Access is denied

os.kill(shell_process.pid, signal.SIGTERM)

subprocess.check_output("Taskkill /PID %d /F" % child_pid) 为我工作了任何进程,没有权限错误 见WindowsError: [Error 5] Access is denied

【讨论】:

  • 感谢回复,我正在使用脚本:subprocess.Popen("taskkill /F /IM EXCEL.EXE",shell=True)
【解决方案2】:

根据this SO 帖子,无法关闭使用os.startfile() 打开的文件。 this Quora 帖子中讨论了类似的事情。

但是,正如 Quora 帖子中所建议的,使用不同的工具打开您的文件,例如 subprocessopen(),将授予您更大的控制权来处理您的文件。

我假设您正在尝试读取数据,因此关于您不想手动关闭文件的评论,您始终可以使用 with 语句,例如

with open('foo') as f:
    foo = f.read()

有点麻烦,因为您还必须做一个read(),但它可能更适合您的需求。

【讨论】:

  • 或者使用Pathlib你可以使用foo = Path('foo').read_text(),同时打开、读取和关闭你的文件。
【解决方案3】:

os.startfile() 有助于启动应用程序,但无法退出、终止或关闭已启动的应用程序。

另一种选择是以这种方式使用子流程:

import subprocess
import time

# File (a CAD in this case) and Program (desired CAD software in this case) # r: raw strings
file = r"F:\Pradnil Kamble\GetThisOpen.3dm"
prog = r"C:\Program Files\Rhino\Rhino.exe"

# Open file with desired program 
OpenIt = subprocess.Popen([prog, file])

# keep it open for 30 seconds
time.sleep(30)

# close the file and the program 
OpenIt.terminate() 

【讨论】:

    【解决方案4】:

    为了正确获取孩子的pid,可以添加一个while循环

    
    import subprocess
    import psutil
    import os
    import time
    import signal
    shell_process = subprocess.Popen([r'C:\Pt_Python\data\1.mp4'],shell=True)
    parent = psutil.Process(shell_process.pid)
    while(parent.children() == []):
        continue
    children = parent.children()
    print(children)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      相关资源
      最近更新 更多