Generate a static COM proxy

Introduction

If you've done any kind of COM automation using Python then you'll probably be familiar with the idea of early vs late-binding of interfaces. To summarise, the COM-support stuff in Python will either generate a class on the fly which represents the COM object you're interested in (late-binding or dynamic proxy), or will make use of a generated Python module which contains the class definition (early-binding or static proxy). The former means that you can attach to any COM object and the built class will simply proxy requests and responses to and fro. The latter means that a certain amount of documentation and validation is then available, but will only work where a typelib exists from which the module can be built.

The great thing is that, a lot of the time you won't care: the general Dispatch mechanism takes care of things for you intelligently. If, however, you can't allow writing static proxy files, say within a zipped application, then you'll want to specify dynamic dispatch. Conversely, if you want the extra information the static proxy brings, you'll want to ensure the static module is built.

Use a dynamic proxy

To use a dynamic version of the proxy class, either call .Dispatch without ever having generated a static proxy, or explicitly invoke the dynamic dispatch mechanism. In the example below, the xl.__module__ indicates whether it's truly dynamic (has a module of 'win32com.client.dynamic') or a generated proxy (has a module of 'win32com.gen_py.{something}').

import win32com.client

xl = win32com.client.Dispatch ("Excel.Application")
print xl.__module__

# or

xl = win32com.client.dynamic.Dispatch ("Excel.Application")
print xl.__module__

Use a static proxy

To generate a static proxy, you can either call makepy against the appropriate dll or exe, or you can programatically generate a static proxy when you dispatch the object. The former is convenient when, say in the case of Excel, there's a huge hierarchy of objects, each of which needs its own module and class. The latter is convenient when you only need to dispatch specific objects, and can generate proxies on-demand.

Use makepy

from win32com.client import makepy

makepy.main ()
If you don't pass the name of a COM .dll, .exe or type library (.tlb) file, a small dialog will pop up with the names of all registered type libraries. You pick one and click [OK]. Alternatively, you can pass a filename which represents a dispatchable object:
import sys
from win32com.client import makepy

sys.argv = ["makepy", r"c:\windows\msagent\agtctl15.tlb"]
makepy.main ()

Use EnsureDispatch

A fairly painless way of ensuring a static proxy exists for one object is to call the .EnsureDispatch utility function from the gencache module. If a proxy already exists, it will return it; if not, it will generate it and return it. It can be used transparently in place of .Dispatch if you always want early-binding

import win32com.client

xl = win32com.client.gencache.EnsureDispatch ("Excel.Application")
print xl.__module__