Simon Fell > Its just code > Single Instance Apps

Monday, October 13, 2003

To expand on my earlier comments on Chris's book about the Applications and Settings chapter here are the issues I spotted (BTW, don't let this put you off buying the book, its a good book, I'd still recommend it)

Single Instance Apps via a named Mutex

Chris outlines a solution using a named Mutex to detect multiple instances of an application trying to start, and points out that there can be issues when running under terminal services, however the particular problem that Chris outlines (same user with multiple Terminal Server sessions going) doesn't exist, because the mutex names are bound to different scopes, as described in detail in the Platform SDK docs for CreateMutex (and equally completely missing from the .NET docs for the Mutex class), you can prove this to yourself with a simple demo.

using System ;
using System.Threading ;

public class MutexName
        public static void Main(string [] args)
                bool firstInstance = false ;
                Mutex m = new Mutex(true, "SimonsTestMutex", out firstInstance ) ;              
                Console.WriteLine("Mutex created, firstInstance={0}, press any key", firstInstance ) ;
                Console.Read() ;

Run an instance on the console and using the same account another instance from a TS session, now grab ProcessExplorer and fire it up from one of the sessions, you'll notice that the actual name of the console instance mutex is \BaseNamedObjects\SimonsTestMutex but the name of the TS instance is \Sessions\1\BaseNamedObjects\SimonsTestMutex. The TS folks have done the heavy lifting for you.

Passing Command Line Parameters

The chapter goes on to discuss how to pass parameters from the 2nd start attempt to the already running attempt, and outlines a solution based on remoting. There are 2 issues with this, one it uses a localhost:1313 address, of which there is one per box, no good in the face of TS and second there's a potential security issue in the TS case as it's passing the parameters I tried to start the app with to potentially a different user account. I'm not sure how to fix this, you need something that can take advantage of the scoping done for kernel objects, perhaps a named pipe channel would pick up those scopes?? (anyone know)

My final issue was later in the chapter it talks about storing data as serialized instances using the serialization framework, and there's also talks about versioning, but no mention of the potential issues with migrating the serialized data between versions. I did subsequently noticed that there's an appendix on that very topic, so make sure you check that out as well.