0

Is there a way from VBA to kill hanging zombie xlwings Python processes before opening or after closing Excel? I'm happy to take a solution from either VBA or Python, I don't really mind which.

For example, in VBA I could do the following, but this imprecise, I need to kill specific Python processes, namely those resulting from xlwings and those connected to a specific workbook i.e. that contain the MyWorkbook.xlsx in the file name. Is there a way to use TASKKILL in a more precise manner?

Private Sub Workbook_Open()
   Dim KillPython As String
   KillPython = "TASKKILL /F /IM Python.exe"
   Shell KillPython, vbHide
   
   'do more stuff, now I can safely rely that there are no
   'automation errors coming from xlwings' zombie processes
   RunPython("import mymodule; mymodule.do_stuff()")
 
End Sub

In Python I could do the following, which is more precise:

import os
import psutil

my_pid = os.getpid()
my_proc = None
for p in psutil.process_iter():
    if 'python' in p.name() and 'MyWorkbook' in ' '.join(p.cmdline()):
        if p.pid != my_pid:
            p.kill()
        else:
            my_proc = p

# finally try to kill self, if needed
my_proc.kill()

Here there seems to be a relationship between my_pid and the p I am getting as some times it satisfies the condition p.pid != my_pid yet it kills the current process. Maybe there is a parent child process relationship when I match the process names.

On a separate note, why is xlwings always triggering the creation of two Python processes instead of only one?

SkyWalker
  • 13,729
  • 18
  • 91
  • 187
  • 1
    By default Xlwings creates an instance of Excel and the workbook that is being opened so there will be two instances of Excel. Both should be closed when the code completes if exited properly however in some cases a zombie process can be left behind. Using a context manager ensures the Excel processes are cleared up and no other action is required. See this post for using a contex manager and [not] showing the instances; https://stackoverflow.com/questions/74297604/how-to-open-an-existing-workbook-without-creating-an-new-book/74298944#74298944 – moken Dec 13 '22 at 22:32

1 Answers1

1

Try:

import subprocess
subprocess.call(["taskkill", "/f", "/im", "EXCEL.EXE"])
mouwsy
  • 1,457
  • 12
  • 20