Check for running Opera on Windows

Created: 2013-09-23 — modified: 2013-09-23 — tags: opera python windows

Currently (Opera 15-18), when you start Opera on Windows, it spawns itself again and terminates the process you started — so you can't easily wait until the Opera you've started quit. Or can you?

That's how we'll cheat the system: instead of watching after a process with given pid, we'll be watching after a process started from a given folder. And to do this, we'll use GetModuleFileNameEx function. Sample python code (based on work by Eric Koome):

from ctypes import *

def EnumProcesses():
    """
    Based on work by Eric Koome (ekoome@yahoo.com) - license GPL or PSF:
    http://code.activestate.com/recipes/305279-getting-process-information-on-windows/
    """
    psapi = windll.psapi #PSAPI.DLL
    kernel = windll.kernel32 #Kernel32.DLL
    arr = c_ulong * 256
    lpidProcess= arr()
    cb = sizeof(lpidProcess)
    cbNeeded = c_ulong()
    hModule = c_ulong()
    count = c_ulong()
    modname = c_buffer(300)
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_READ = 0x0010
    ret = []
    #Call Enumprocesses to get hold of process id's
    psapi.EnumProcesses(byref(lpidProcess), cb, byref(cbNeeded))
    #Number of processes returned
    nReturned = cbNeeded.value/sizeof(c_ulong())
    #Drop unused returned values
    pidProcess = [i for i in lpidProcess][:nReturned]
    for pid in pidProcess:
        #Get handle to the process based on PID
        hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, pid)
        if not hProcess:
            continue
        #Get filename
        psapi.GetModuleFileNameExA(hProcess, None, modname, sizeof(modname))
        kernel.CloseHandle(hProcess)
        if modname.value == '?':
            continue
        ret.append(modname.value)
    #Clean up
    modname.value = '0'
    return ret

if __name__ == '__main__':
    print '\n'.join(EnumProcesses())

Run like this — and it prints full pathnames of all processes it could enumerate.

You can also import this file as a module and search in output of EnumProcesses() function (it's a list) for a process started from given folder (given that above code saved to a file process_lister.py):

import time

from process_lister import EnumProcesses

process_location = 'C:\Program Files (x86)\Opera'

while True:
    procs = EnumProcesses()
    found = len(filter(lambda proc: proc.startswith(process_location), procs)) > 0
    if not found:
        exit()
    time.sleep(1)

Note that since in above code process_location does not have terminating \, it will wait for Operas in all folders, including, for example, both C:\Program Files (x86)\Opera Next and C:\Program Files (x86)\Opera My

Or you can do some other stuff. Feel free to reuse this code however original license (GPL or PSF) allows you, and feel free to drop me a line, if you think your comment will be interesting for me!