# Wednesday, March 17, 2004

You have probably noticed by now that Pocket PC applications built with .NET Compact Framework 1.0 are single-instance. If you try to launch it while one copy is already running, that copy will be reactivated and brought to foreground. While very convenient and compliant with PPC Design Guidelines, sometimes it is a bit too helpful.

Let's take a look at what happens when you launch your CF application. On the outside a CF application is a standard executable with PE header and entry point. The entry point is a single line of assembly code:

jmp mscoree!__CorExeMain

Upon startup CF implementation of mscoree looks for a window with a class #NETCF_AGL_PARK and title set to the current process executable full path (\Program Files\MyApp\MyApp.exe). If found, the runtime presumes that the current application is already running. In this case it will be reactivated. To do this the abovementioned window is sent a message 0x8001, and then the new instance quits . In the previously active instance upon receiving of the message 0x8001 the WindowProc of #NETCF_AGL_PARK window will perform a series of steps ending with a call to SetForegroundWindow. Notice that the call to SetForegroundWindow is passed the handle of  GetWindow(<#NETCF_AGL_PARK window>, GW_HWNDPREV).
Unfortunately there are cases when you need more than simply reactivate the previous instance. The most notable example is using a CF app as a target for CeLaunchAppAtXXX function. Problem is that the second instance quits before your managed code has a chance to execute, so there is not much you can do even if you would like to implement your own logic for detecting/activating previous instance.
The solution for disabling this "single-instance" behavior is rather obvious from the above description. All we need to do is to rename our #NETCF_AGL_PARK window. The window handle can be located using FindWindow function. The class name is #NETCF_AGL_PARK and the title is identcal to the full assembly module path:
Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedPath. Then we simply use SetWindowText to alter window title.
 
12/20/04: Update
It appears that the name of the window class has changed in SP2. The new name is #NETCF_AGL_PARK (with a trailing underscore). The rest of the informatin above stands.
Wednesday, March 17, 2004 12:37:08 PM (Pacific Standard Time, UTC-08:00)  #    Comments [21]  |