The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

How to find other instances of running app?

Lets say you are writing an application.  The user starts it once.  When they try to start it again, the app just exits because it finds a "lock" file.

A better design would be to, before it exits, find the already running app and bring it back into the foreground -- the user is probably launching it again because they don't realize it's already running (or because they think that's how they can find it).

But how do you get a handle to a window in another application?  Sounds like a violation of the security model...
Michael B
Wednesday, August 03, 2005
 
 
Dino Send private email
Wednesday, August 03, 2005
 
 
I believe there's actually an hPreviousInstance (handle) passed during one of the standard Win32 GUI initialization functions.  Maybe WinMain?
Marco Arment Send private email
Wednesday, August 03, 2005
 
 
A good way is to use an event, via CreateEvent/OpenEvent.

This is the same as a mutex (it can have an individual string name), but it can also be "signaled" (basically, it can be ON and OFF).

Your second instance will check for the existence of a particular named event (make it highly unique such as "FooBar 1.2 70325D28-E280-4e86-8EED-1AB2A3691653)", and if it exists, signal it (via PulseEvent) and exit.

The main loop of your application will need to include a MsgWaitForMultipleObjects which waits on that event being signaled, but also returns when a message is available for regular processing.

If the event is signaled (by the second instance), this means the second instance has requested your existing instance to come to foreground. This is when you call SetForegroundWindow or a similar function to bring your app to the front.

A sample message loop:

http://rafb.net/paste/results/ecQJS322.html
Alex Send private email
Wednesday, August 03, 2005
 
 
Google for Singleton pattern
Hakan Send private email
Wednesday, August 03, 2005
 
 
My fading long-term memory does recall an hPreviousInstance handle from some Win32 api but I can't seem to find it.  This is of course assuming you have a Win32 only app....

Going along with this assumption, if you might also try looking at the process list that Windows has.

Try looking up the Win32 api functions:
OpenProcess
ProcessFirst
ProcessLast
CreateToolHelpSnapshot

there's also a PROCESSENTRY32 struct somewhere around...
Paul Norrie Send private email
Wednesday, August 03, 2005
 
 
The standard way is to use a mutex to find out if your app is already running. Also, register a globally unique message with RegisterWindowMessage. Then, if your app is already running, broadcast that message to all apps, together with some information, for example a handle to a memory mapped file with a command line or something similar, and quit. Install a message handler that listens for the registered message, activate the app and possibly open files from the passed command line. This is much less error-prone than the event approach.
Frederik Slijkerman Send private email
Wednesday, August 03, 2005
 
 
The document "Designed for Microsoft Windows XP” Application Specification" has some sample code for dealing with this issue - while it covers Win9x, WinXP adds in some amusing extra issues with fast user switching that you'll probably want to handle.


I believe this is a direct link to the download page:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=209E3D65-F0BE-4EEF-8602-73BB9BC29D54

Wednesday, August 03, 2005
 
 
> I believe there's actually an hPreviousInstance (handle) passed during one of the standard Win32 GUI initialization functions.  Maybe WinMain?

That hasn't been usable since windows 3.x  Although it's still there, the handle is always NULL.

Wednesday, August 03, 2005
 
 
Wow, no given handle since Win3.x - I knew it was a long time since I used Win32 api in my old Borland compiler with 256 colours and 640x480 resolution. 

** Goes off to reminisce about when programmers got excited about event-driven applications **
Paul Norrie Send private email
Thursday, August 04, 2005
 
 
typedef void (WINAPI *PROCSWITCHTOTHISWINDOW)(HWND,BOOL);

////////////////////////////////////////////////////////
// Are we already running? If so switch to that process

  HWND hwnd = FindWindow(szAppName,szAppName);
 
  if(hwnd != NULL)
  {
    HMODULE  hUser32 = GetModuleHandle(TEXT("user32"));
   
    PROCSWITCHTOTHISWINDOW SwitchToThisWindow =
      (PROCSWITCHTOTHISWINDOW)GetProcAddress 
          (hUser32,"SwitchToThisWindow");
    
    SwitchToThisWindow(hwndMain,TRUE);
    return 0;
  }

/////////////////////////////////////////////////////

Hope that helps.
Petar Send private email
Friday, August 05, 2005
 
 
Oopps. The "hwndMain" should be just "hwnd".
Petar Send private email
Friday, August 05, 2005
 
 
That won't work when the window title includes the currently open document. E.g. "people.doc - FooBar 1.2"
Alex Send private email
Friday, August 05, 2005
 
 
That's one good reason why not to use FindWindow. Generally we've registered a system event and used a mutex to deal with multiple instances. When the second instance was launched, it would check the mutex and fire the event if the mutex exists. The event would then bring the first instance to the foreground.
QADude
Friday, August 05, 2005
 
 
See also latest MSDN Magazine for an article about it:

http://msdn.microsoft.com/msdnmag/issues/05/09/NETMatters/default.aspx
Patric Send private email
Thursday, August 11, 2005
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz