[CentralOH] SingleInstance Recipe (Windows)

Mark Erbaugh mark at microenh.com
Wed Aug 4 01:45:13 CEST 2010


I've been looking into ways to make sure that only one instance of a Python application runs. This is for Windows.

ActiveState Recipe #474070 is one way:

from win32event import CreateMutex
from win32api import CloseHandle, GetLastError
from winerror import ERROR_ALREADY_EXISTS

class singleinstance:
    """ Limits application to single instance """

    def __init__(self):
        self.mutexname = "testmutex_{D0E858DF-985E-4907-B7FB-8D732C3FC3B9}"
        self.mutex = CreateMutex(None, False, self.mutexname)
        self.lasterror = GetLastError()
    
    def aleradyrunning(self):
        return (self.lasterror == ERROR_ALREADY_EXISTS)
        
    def __del__(self):
        if self.mutex:
            CloseHandle(self.mutex)


#---------------------------------------------#
# sample usage:
#

from singleinstance import singleinstance
from sys import exit

# do this at beginnig of your application
myapp = singleinstance()

# check is another instance of same program running
if myapp.aleradyrunning():
    print "Another instance of this program is already running"
    exit(0)

# not running, safe to continue...
print "No another instance is running, can continue here"

However (apart from the typos), playing with it, I found that the only reason it worked was that the application instances involved were terminating and Windows was cleaning things up. When I was playing with it in a couple of interactive python windows, I found that it did not work as expected.  I looked into the cause and came up with an alternative that does work.

import win32event
import win32api

class SingleInstance:
    """
    Limits application to single instance

    sample usage:

    ==========
    import singleinstance
    import sys

    myApp = singleinstance.SingleInstance('name')
    if myApp.fail:
        print "Another instance of this program is already running
        sys.exit(0)
    ==========
    
    Make sure myApp is a global and exists as long as the application
    is running.

    The key is that myApp hangs on to a copy of the mutex (self.mutex)
    only if the call to CreateMutex is successful.

    When myApp goes out of scope, self.mutex is released and another
    instance of the application can run.
    """

    def __init__(self, name):
        """
        name - name of mutex
        """
        mutex = win32event.CreateMutex(None, False, name)
        self.fail = win32api.GetLastError() != 0
        if not self.fail:
            self.mutex = mutex
        

Comments are welcome.

Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/mailman/private/centraloh/attachments/20100803/389e1375/attachment.html>


More information about the CentralOH mailing list