Limiting Instances

The other day, there was a question on the PLT Scheme list about reusing an existing DrScheme Scheme instance when you double click on a Scheme source file. DrScheme has a non-trivial startup time, so this is a very good idea. In the good old days (i.e. back when I did Win16 programming), it was pretty straightforward to limit a Windows application to a single instance; the OS told you: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int cmdShow) . In Win32, hPrevInstance is always NULL, so you need some other method. I was doing a little research on this and found a few good articles: Essentially, the techniques boil down to the following:
  • Use FindWindow to locate another instance of your toplevel window. This is problematic for
  • Use a Global Atom as a flag. This has the disadvantage that you still need FindWindow to locate a window handle to set focus to.
  • Use a variable in shared memory to act as a flag or semaphore
  • Use a mutex. CreateMutex is an atomic operation, so there's no race condition.
The one wrinkle with this is this question: what does it mean to reuse an existing instance? In Windows, you can have terminal services installed, which can result in multiple desktops being open, even under the same user account. Newcomer distills this into 4 cases, since DrScheme is an interactive program, the applicable case is probably "Avoiding multiple instances started in the same desktop, but allowing multiple instances to run as long as each one is in a separate desktop.". Newcomer includes code to handle all 4 cases, but in this particular case, a unique name is derived by concatenating a GUID with the desktop name for the current user.

— Gordon Weakliem at permanent link