Few days ago I had one of my coding week-ends. They are getting rare and rare so I make a big deal out of it. I was back to my pet project, reshaping and adding some make up. I am hoping to write some about it soon. Good thing with having pet projects, you don’t have to play by the rules. You can start with changing a tiny GUI element and end up re-writing all. That’s what happened more or less. Before I started feeling dizzy and shaking I managed to come to the point where everything started working again (sounds familiar?).
Along the journey I came where python meets automation objects. I thought it would be cool if I add few touches to Visual Studio which I use daily for development. Although it is not as popular as Microsoft Word, few attempts in google returns pretty reliable results. You can retrieve an automation object to talk with Visual Studio from your script. The problem is I often run multiple instances of Visual Studio jumping from one another it for anything useful I should be able to create an automation object for a specific Visual Studio instance. Unlikely, Visual Studio is a bit different than Microsoft Word. In Word you actually have a single instance with multiple documents, so accessing a specific application instance is not your concern. Long story short, I spent quite a lot of time trying to figure out how to access a specific application instance, for example the one which has the focus at the moment. I tried both google and google code search (which is one of my favorite while working with python) with all alternative queries that I could think of.
Did you know that google search might become addicted? With each query you come close to the answer than it falls away from you again. Finally when I was going old school (asking real human beings around) one of the queries returned something. Unfortunately I was so happy I forgot to record the lucky query. Below is the piece of code that made its way to my application. It traverses a list of running objects checking their name to find the visual studio instances. If a list of candidate process IDs are given, it tries to eliminate the running instances by the process ID. Display name of the running instance contains the application class together with process ID. Using python windows extensions you can get the window handle for the active window and check for the process ID for the found window handle (this function returns a list of process IDs).
Let’s see if this one will end up in somebody’s lucky query…
pids = win32process.GetWindowThreadProcessId(hwnd)
ctx = pythoncom.CreateBindCtx()
rot = pythoncom.GetRunningObjectTable()
for mk in rot:
name = mk.GetDisplayName(ctx, None)
if name.find('VisualStudio.DTE') < 0:
continue
pos = name.rfind(':')
if pos < 0:
continue
name = name[pos + 1:]
val = int(name)
if val in pids:
obj = rot.GetObject(mk)
interface = obj.QueryInterface (pythoncom.IID_IDispatch)
dte = com.client.Dispatch (interface)
break