Excel.exe 如果出现任何错误后可见 false,则进程继续 运行

Excel.exe process keeps on running if visible false after any error

通常我使用下面的代码在后台打开一个excel工作簿:

import xlwings as xw

app = xw.App(visible=False)
wb = xw.Book(filename)
sheet = wb.sheets['sheet1']

当我执行包含上述行的代码时(使用 visible=False),有时我没有正确编码并收到错误消息。在这种情况下,EXCEL.EXE 进程在后台进程列表中保持打开状态(在 windows 10 上的 windows 任务管理器中)。 如果我收到一条错误消息,是否有解决方案可以在后台关闭使用 python 代码打开的特定 excel 进程?否则,每次执行代码时出现错误,都会将一个额外的 excel 进程添加到进程列表中,从而导致性能降低。

目前,我的解决方法是在 python 脚本的顶部添加以下行,但这会关闭所有 excel 进程:

import subprocess
subprocess.call(["taskkill", "/f", "/im", "EXCEL.EXE"])

我的 objective 是仅关闭使用 python 脚本打开的特定进程。

首选方案
xlwings在v0.24.3中添加了一个solution来解决这个问题:
[增强] xlwings.App() 现在可以用作上下文管理器,确保 Windows 上没有剩余的僵尸进程,即使您使用隐藏实例和您的代码失败。因此建议尽可能使用它,例如:

import xlwings as xw
with xw.App(visible=False) as app:
    wb = xw.Book("test.xlsx")
    sheet = wb.sheets['sheet1']
    # To evoke an error, I try to call an non-exisiting sheet here.
    nonexistent_sheet["A1"]

with 行可防止 EXCEL.EXE 进程在 windows 任务管理器中保持打开状态,即使代码中存在错误也是如此。

v24.0.3之前的解决方法
不太优雅:错误被 except 块捕获,这意味着您脚本的主要目的应该写在 try 块中。

import xlwings as xw
import traceback

app = xw.App(visible=False)
wb = xw.Book("test.xlsx")
sheet = wb.sheets['sheet1']

# Do what you want here. To evoke an error, I try to call an non-exisiting sheet here.
try:
    not_existing_sheet["A1"]

# Sources for except block:  and 
except BaseException:
    print(traceback.print_exc())
    app.quit()

我找到了这段代码 here。使用此 psutil 库,它会获取您拥有的所有进程 运行ning,检查进程中是否有字符串(即 Adob​​e,EXCEL)并终止这些进程。使用 Python 3 和 Windows 10 可以很好地杀死 Excel 会话,这些会话在我用 Win32com 打开和“关闭”它们后在后台继续 运行。

import psutil

def main():
    '''Process kill function'''    
    for proc in psutil.process_iter():
        # check whether the process name matches
        # print(proc.name())
        if any(procstr in proc.name() for procstr in\
            ['Adobe', 'EXCEL']):
            print(f'Killing {proc.name()}')
            proc.kill()


if __name__ == "__main__":
    main()