[cx-freeze-users] Use of win32com.client for COM client programming
Brought to you by:
atuining
From: Craig M. <mcq...@ed...> - 2010-06-07 02:32:07
|
Hello, I've got a program that is using COM client programming for Excel and National Instruments TestStand. It uses these types of lines in Python to generate the COM interface: # Run makepy process for all of: # "Microsoft Office 10.0 Object Library" # "Microsoft Office 11.0 Object Library" # "Microsoft Office 12.0 Object Library" # referenced by its CLSID and version. This CLSID and version information was obtained # using the command: makepy.py -i "Microsoft Office 10.0 Object Library" win32com.client.gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 2) win32com.client.gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 3) win32com.client.gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 4) # Load the "Microsoft Office x.0 Object Library" type library for constants # such as win32com.client.constants.msoAutomationSecurityForceDisable # This is not required if the makepy process has been run automatically (see above). # It is only required if makepy.py was run manually as a separate installation step. win32com.client.gencache.GetModuleForCLSID("{000672AC-0000-0000-C000-000000000046}") # Run makepy process for "Microsoft Excel 11.0 Object Library" # referenced by its CLSID and version. This CLSID and version information was obtained # using the command: makepy.py -i "Microsoft Excel 11.0 Object Library" win32com.client.gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 5) #win32com.client.gencache.GetModuleForCLSID("{00024500-0000-0000-C000-000000000046}") (I'm not sure if it's necessary to call win32com.client.gencache.EnsureModule for each minor version number, but that aside...) This doesn't seem to work well when the program is converted using cx_Freeze. It seems that win32com.client.gencache is not willing to dynamically create interfaces since it regards the cache as "read-only". Well, it "kind-of" seems to work, in that Excel COM can be initiated by xl_app = win32com.client.DispatchEx("Excel.Application") however constants are not recognised--e.g. win32com.client.constants.xlUpdateLinksNever In the past, I've used py2exe and found this trick (that I found somewhere on the 'net) seems to work: if win32com.client.gencache.is_readonly == True: #allow gencache to create the cached wrapper objects win32com.client.gencache.is_readonly = False # under py2exe the call in gencache to __init__() does not happen # so we use Rebuild() to force the creation of the gen_py folder win32com.client.gencache.Rebuild() # NB You must ensure that the python...\win32com.client.gen_py dir does not exist # to allow creation of the cache in %temp% However it doesn't seem to achieve the same effect with cx_Freeze. Any ideas? At the moment, I've got the program running okay with the following steps: 1) Run the original Python program. That should generate the COM client interface files under Python's directory for win32com.gen_py. E.g. C:\Python26\Lib\site-packages\win32com\gen_py 2) In the setup.py program for cx_Freeze, specify options for 'build_exe', specifically the 'packages' option, with a list that includes 'win32com.gen_py'. E.g.: setup( ... options = { 'build_exe': { ... 'packages': [ 'win32com.gen_py' ], ... }, ... ) That includes my PC's gen_py cache contents in the cx_Freeze build, and the program runs okay then. But I assume it would not run properly on a PC that contained e.g. a different version of Excel. Is there a better way to do this COM client type lib stuff with cx_Freeze? Regards, Craig McQueen |