DEV Community

Luca Salvarani
Luca Salvarani

Posted on • Edited on

Basic operations

Let's dive into the basic operations...

Dispatch methods

A COM object can be created in various ways:

  1. win32com.client.Dispatch
  2. win32com.client.DispatchEx
  3. win32com.client.DispatchWithEvents
  4. win32com.client.dynamic.Dispatch
  5. win32com.client.gencache.EnsureDispatch

1. win32com.client.Dispatch

This is the most common way to start an instance of a COM object.
It tries to automatically detect and use the best dispatching method (early or late binding).
In fact, behind the scenes, this method uses dynamic.Dispatch or gencache.EnsureDispatch. The order in which the dispatch types are tested is the following (the first valid dispatch is returned):

  1. Early binding (also called "Static Dispatch") if possible
  2. Late binding (also called "Dynamic Dispatch") otherwise
from win32com import client

excel = client.Dispatch('Excel.Application')
Enter fullscreen mode Exit fullscreen mode

2. win32com.client.DispatchEx

Same as win32com.client.Dispatch, but allows to create a DCOM object on a remote machine.

For example, in the following code snippet, we will open Excel on the server with IP 192.168.1.17:

from win32com import client

server_name = "192.168.1.17"
excel = client.DispatchEx('Excel.Application', server_name)
Enter fullscreen mode Exit fullscreen mode

3. win32com.client.DispatchWithEvents

Same as win32com.client.Dispatch, but allows to respond to events triggered by the application.

For example, in the following code a message will be printed on screen every time a user performs a double click on a cell:

from win32com import client

class ExcelEvents:
    def BeforeDoubleClick (self, Target, Cancel):
        print("A double click has occurred")

excel = client.DispatchWithEvents('Excel.Application', ExcelEvents)
Enter fullscreen mode Exit fullscreen mode

4. win32com.client.dynamic.Dispatch

This method completely bypasses the COM cache, directly querying the object instead. It can solve some problems with the cache, but it is slower and is subject to application rules (for example in Excel everything is case insensitive, so excel.VISIBLE is equal to excel.Visible) but it can

from win32com import client

excel = client.dynamic.Dispatch('Excel.Application')
Enter fullscreen mode Exit fullscreen mode

PRO:

  • Case insensitive lookup

CONS:

  • Slower than gencache.EnsureDispatch

5. win32com.client.gencache.EnsureDispatch

This method forces the use/creation of the cache.

The cache can be found inside the folder: C:\Users\{USERNAME}\AppData\Local\Temp\gen_py

from win32com import client

excel = client.gencache.EnsureDispatch('Excel.Application')
Enter fullscreen mode Exit fullscreen mode

Known bugs

Using this method you might encounter some bugs involving the cache, like the infamous AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'.

This problem in particular can be solved in two ways:

  1. deleting the cache folder (%TEMP%/gen_py) so that the next call to EnsureDispatch will trigger a cache refresh;
  2. forcing a cache refresh yourself;

Then all you need to do is running again the client.gencache.EnsureDispatch function and you'll be good to go!

PRO:

  • Faster than dynamic.Dispatch thanks to the cache

CONS:

  • More subject to errors (most notably the AttributeError cited before) caused by the cache

Top comments (0)