22

这是我的代码,我为VBA、.NET 框架找到了很多答案,而且很奇怪。当我执行此操作时,Excel 将关闭。

from win32com.client import DispatchEx
excel = DispatchEx('Excel.Application')
wbs = excel.Workbooks
wbs.Close()
excel.Quit()
wbs = None
excel = None # <-- Excel Closes here

但是当我执行以下操作时,它不会关闭。

excel = DispatchEx('Excel.Application')
wbs = excel.Workbooks
wb = wbs.Open('D:\\Xaguar\\A1.xlsm')
wb.Close(False)
wbs.Close()
excel.Quit()
wb = None
wbs = None
excel = None  # <-- NOT Closing !!!

我在堆栈溢出问题中找到了一些可能的答案Excel 进程在互操作后仍然打开;传统方法行不通。问题是那不是 Python,我找不到Marshal.ReleaseComObjectGC. 我查看了所有演示...site-packages/win32com和其他演示。

如果我能得到PID并杀死它,即使它也不会打扰我。

我在Kill process based on window name (win32)中找到了一种解决方法。

可能不是正确的方法,但解决方法是:

def close_excel_by_force(excel):
    import win32process
    import win32gui
    import win32api
    import win32con

    # Get the window's process id's
    hwnd = excel.Hwnd
    t, p = win32process.GetWindowThreadProcessId(hwnd)
    # Ask window nicely to close
    win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
    # Allow some time for app to close
    time.sleep(10)
    # If the application didn't close, force close
    try:
        handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
        if handle:
            win32api.TerminateProcess(handle, 0)
            win32api.CloseHandle(handle)
    except:
        pass

excel = DispatchEx('Excel.Application')
wbs = excel.Workbooks
wb = wbs.Open('D:\\Xaguar\\A1.xlsm')
wb.Close(False)
wbs.Close()
excel.Quit()
wb = None
wbs = None
close_excel_by_force(excel) # <--- YOU #@#$# DIEEEEE!! DIEEEE!!!
4

5 回答 5

12

尝试这个:

wbs.Close()
excel.Quit()
del excel # this line removed it from task manager in my case
于 2013-11-18T13:25:45.773 回答
4

对我有用的是确保取消引用您在此过程中分配的任何变量,如下所示:

import win32com.client as win32

fileDirectory = 'Hello World.xlsx'

#excelFile = win32.Dispatch('Excel.Application')
excelFile = win32.gencache.EnsureDispatch('Excel.Application')

excelFile.Visible = True
excelFile.DisplayAlerts = True

wb = excelFile.Workbooks.Open(fileDirectory)
ws = wb.Sheets("Sell")

ws.Range("D1").Value = "Hello World!"
ws = None

wb.Close(False)
wb = None

excelFile.Quit()
excelFile = None

它适用于任一 Dispatch 格式。

于 2020-08-19T17:13:43.960 回答
3

我在使用 Excel 的文件中有这个:

self.excel.Application.Quit()
于 2012-08-07T16:33:03.167 回答
0

我喜欢通过 win32com 杀死 Excel 进程并不总是那么可靠。这些包括excel.Application.Quit(), 和del excel如上所述。

我发现确保它已死的唯一方法是物理终止该EXCEL.EXE进程:

import psutil

def kill_excel():
    for proc in psutil.process_iter():
        if proc.name() == "EXCEL.EXE":
            proc.kill()

缺点是这个脚本显然会杀死当前正在运行的所有 excel 进程。如果您可以忍受这一点,那么这不是一个糟糕的选择。

于 2021-04-01T07:50:21.283 回答
0

Python 应该处理 COM 对象的生命周期。刚设置excel = None。请参阅此内容以供参考:

# CH9 says: Python manages COM lifetimes automatically for you; when your excel 
#           variable is no longer used, Excel automatically closes. In Python,
#           the simplest way to remove this variable is to assign it to another 
#           value. If you use the following code, notice that Excel vanishes 
#           from the screen; it knows there are no longer any programs referring to it. 

源代码:

http://www.icodeguru.com/WebServer/Python-Programming-on-Win32/ch05.htm#:~:text=xl%20=%20None

于 2020-09-09T06:06:18.683 回答