Aspen COM object introspection

| categories: programming | tags: aspen

COM programming is a bit more difficult than normal python programming. The main reason is the functions on the objects are not easy to inspect, and they are not always well documented. Let us look at this for the Aspen COM interface.

import win32com.client as win32

aspen = win32.Dispatch('Apwn.Document')
print aspen
print dir(aspen)
Aspen Plus 27.0 OLE Services
['_ApplyTypes_', '_FlagAsMethod', '_LazyAddAttr_', '_NewEnum', '_Release_', '__AttrToID__', '__LazyMap__', '__call__', '__doc__', '__eq__', '__getattr__', '__getitem__', '__init__', '__int__', '__len__', '__module__', '__ne__', '__nonzero__', '__repr__', '__setattr__', '__setitem__', '__str__', '_builtMethods_', '_enum_', '_find_dispatch_type_', '_get_good_object_', '_get_good_single_object_', '_lazydata_', '_make_method_', '_mapCachedItems_', '_oleobj_', '_olerepr_', '_print_details_', '_proc_', '_unicode_to_string_', '_username_', '_wrap_dispatch_']

These are not that helpful. The COM object is so-called "late-bound" which means there is no information available about the methods. To get an "early-bound" object we have to do some work. We have to run the makepy.py utility which will generate a python interface with the methods. I found the makepy.py function like this:

import os
import win32com.client as win32
print os.path.split(win32.__file__)[0]
print os.path.exists(os.path.join(os.path.split(win32.__file__)[0], 'makepy.py'))
C:\Users\jkitchin\AppData\Local\Enthought\Canopy\System\lib\site-packages\win32com\client
True

So, change to the directory above, and run makepy.py. This will pop a window with a lot of libraries to select from. Select "Aspen Plus GUI 27.0 Type Library (10.0)" and click ok. You will see some output like this.

PS C:\Users\jkitchin\AppData\Local\Enthought\Canopy\System\lib\site-packages\win32com\client> python makepy.py
Generating to C:\Users\jkitchin\AppData\Local\Temp\gen_py\2.7\8E567520-F9BA-11CF-90B2-0000C0A810C4x409x16x0.py
Building definitions from type library...
Generating...
Importing module

That command created a new python module that contains the methods available. Luckily, you do not have to do anything special to use it. The new module will automatically be loaded. Let us see an example.

import win32com.client as win32

aspen = win32.Dispatch('Apwn.Document')
print aspen
print dir(aspen)
print
print dir(aspen.Engine)
print
import inspect
print inspect.getargspec(aspen.InitFromArchive2)
Aspen Plus 27.0 OLE Services
['Activate', 'AdviseParent', 'CLSID', 'Choose', 'Close', 'CreateRouteTree', 'DeleteSelection', 'EditCompoundDocument', 'Export', 'Generate', 'GetNew', 'GetNew3', 'Import', 'InitFromArchive', 'InitFromArchive2', 'InitFromArchive3', 'InitFromFile', 'InitFromFile2', 'InitFromTemplate', 'InitFromTemplate2', 'InitFromXML', 'InitNew', 'InitNew2', 'LoadLink', 'NewSelection', 'Readback', 'Reconcile', 'Reinit', 'Restore', 'Restore2', 'RootModel', 'Run', 'Run2', 'RunScript', 'Save', 'Save2', 'SaveAs', 'SaveAs2', 'SaveLink', 'SaveSelection', 'Selection', 'SetCompat', 'SetParent', 'UIDisable', 'WriteArchive', 'WriteArchive2', '_ApplyTypes_', '__call__', '__doc__', '__eq__', '__getattr__', '__init__', '__int__', '__module__', '__ne__', '__repr__', '__setattr__', '__str__', '__unicode__', '_get_good_object_', '_get_good_single_object_', '_oleobj_', '_prop_map_get_', '_prop_map_put_', 'coclass_clsid']

['AddStopPoint', 'CLSID', 'ClearStopPoints', 'ConnectionDialog', 'DeleteStopPoint', 'EngineFilesSettings', 'ExportReport', 'GetStopPoint', 'Host', 'HostDescription', 'MoveTo', 'OptionSettings', 'ProcessInput', 'Reinit', 'ReinitializeEO', 'Run', 'Run2', 'RunSettings', 'SetEngineFilesSettings', 'SetOptionSettings', 'Step', 'Stop', 'StopPoints', 'SynchronizeEO', '_ApplyTypes_', '__doc__', '__eq__', '__getattr__', '__init__', '__module__', '__ne__', '__repr__', '__setattr__', '_get_good_object_', '_get_good_single_object_', '_oleobj_', '_prop_map_get_', '_prop_map_put_', 'coclass_clsid']

ArgSpec(args=['self', 'filename', 'host_type', 'node', 'username', 'password', 'working_directory', 'failmode'], varargs=None, keywords=None, defaults=(<PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>, <PyOleEmpty object at 0x0000000001D36BB0>))

This is much more useful! We can see all the methods of a COM object! See this reference for more details: http://oreilly.com/catalog/pythonwin32/chapter/ch12.html#49339.

Copyright (C) 2013 by John Kitchin. See the License for information about copying.

org-mode source

Discuss on Twitter