Open
Description
Code below should be tested in some way:
def _create_instance(app_id):
def __create_instance(app_id):
import pythoncom
from win32com.client import gencache
# EnsureDispatch use early binding but will reuse an existing instance,
# while DispatchEx creates an new application but uses late binding.
# We want both a new instance and use early binding.
app_id = pythoncom.CoCreateInstanceEx(app_id, None, pythoncom.CLSCTX_SERVER, None,
(pythoncom.IID_IDispatch,))[0]
if gencache.is_readonly:
# needed for "frozen" apps
gencache.is_readonly = False
gencache.Rebuild()
return gencache.EnsureDispatch(app_id)
# open an excel instance via win32com "EnsureDispatch" so that we flag Excel as using early binding.
# it is much faster than late binding BUT sometimes (I don't know the
# precise circumstances yet -- when Excel is updated?) it gets corrupt and nothing works until you re-generate them.
# Note that this only needs to be done _once_ per machine.
# This can also be done explicitly on the command line in two different ways:
# * to generate one big file with bindings for all Excel objects:
# python -m win32com.client.makepy Excel.Application
# * to flag "Excel" as using early binding. Bindings will be generated as many small files as needed:
# python -c "from win32com.client import gencache;gencache.EnsureDispatch('Excel.Application')"
# In case something goes wrong, one can go back to late binding by removing generated bindings from:
# 'C:\\Users\\<user>\\AppData\\Local\\Temp\\gen_py\\3.6'
try:
return __create_instance(app_id)
except AttributeError:
from win32com import __gen_path__
from shutil import rmtree
rmtree(__gen_path__)
return __create_instance(app_id)