python - Ensure that process started by COM connection is killed -
i'm automating minitab 17 using python's win32com
library, , while of commands execute correctly, can't seem process started minitab process exit when script ends. structure looks like
from myapi import get_data import pythoncom win32com.client import gencache def process_data(data): # in case of threading pythoncom.coinitialize() app = gencache.ensuredispatch('mtb.application') try: # processing pass finally: # app-specific command supposed close software app.quit() # ensure object released del mtb # in case of threading pythoncom.couninitialize() def main(): data = get_data() process_data(data) if __name__ == '__main__': main()
i don't exceptions raised or error messages printed, mtb.exe
process still listed in task manager. more frustrating if run following in ipython session:
>>> win32com.client import gencache >>> app = gencache.ensuredispatch('mtb.application') >>> ^d
the minitab process closed immediately. observe same behavior in normal python
interactive session. why process closed correctly when running in interactive session not in standalone script? done differently there isn't being performed in script?
i've tried running process_data
in threading.thread
, in multiprocessing.process
no luck.
edit:
if have script containing nothing but
from win32com.client import gencache app = gencache.ensuredispatch('mtb.application')
then when run see mtb.exe
process in task manager, once script exits process killed. instead question why matter if com object declared @ top-level vs. inside function?
i don't have minitab can't verify try forcing shutdown of com server setting app = none after call app.quit? python uses ref counting manage object life cycle, assuming there no other refs app setting none should cause finalized immediately. have seen cause similar issues. should not need weak reference, else going on. following, based on answer, should work:
def process_data(mtb, data): try: mtb.do_something(data) finally: mtb.quit() def main(mtb): data = get_data() process_data(mtb, data) if __name__ == '__main__': pythoncom.coinitialize() mtb = gencache.ensuredispatch('mtb.application') main(mtb) mtb.quit() mtb = none pythoncom.couninitialize()
Comments
Post a Comment