See if an Excel workbook is open

Introduction

Although the example is specifically about an Excel workbook, really it's demonstrating the existence of the Running Object Table. Objects which have some sort of a name, a moniker, can register with the ROT to be looked up by other applications. Not all objects are registered; it's the COM server's choice whether and how to register its moniker-based objects by calling the ROT's Register method.

The Microsoft Office applications do register their documents with the ROT so, for the purposes of demonstration, we'll start up an Excel spreadsheet and look for it in the ROT.

The Running Object Table via pywin32

You access the Running Object Table by means of the pythoncom module which exposes the GetRunningObject function. This returns a Python interface to the underlying ROT object, which you can iterate over to look for running objects, register an object and its moniker, or look up an object from an existing moniker.

It's implemented in PyIRunningObjectTable.cpp

Find a running workbook

This example starts up a toy Excel document in the shape of a .csv file, which it then hunts for by name through the Running Object Table. Note that, because we use the TEMP environment variable to construct the csv file, its name uses the 8.3 name structure. The moniker name will use the full long file name and so we convert it first.

The pythoncom wrapper around the ROT already exposes a Python iterator around the .EnumRunning method.

The same technique can be used for any application which registers its documents with the ROT: MS Word, PowerPoint, etc.

import os
import pythoncom
import win32api
import win32com.client

FILENAME = win32api.GetLongPathName (os.path.join (os.environ["TEMP"], "temp.csv"))
open (FILENAME, "wb").write ("1,2,3\n4,5,6\n")
obj = win32com.client.GetObject (FILENAME)

context = pythoncom.CreateBindCtx (0)
for moniker in pythoncom.GetRunningObjectTable ():
  name = moniker.GetDisplayName (context, None)
  if name.endswith (FILENAME):
    print "Found", name
    break
else:
  print "Not found"