Programming - Using IPC and a Mutex to implement a single instance application
So, you have an application, but you only want one copy of an
application running at the same time on a single machine. How
hard can it be? Well, quite easy but you need to be able to
understand how C# works. Some people will tell you to search
the process table, but that is inefficient and a very long
winded way of looking at things.
The easiest way, in my opinion is to use a MUTEX to check
wether an application is running:
bool
test;
System.Threading.
Mutexm = newSystem.Threading.Mutex(true, "app", outtest);
if
(!test){
// the app is running so handle it
}else{
//the app is not running so launch the app
}
Now, that solves your single instance issue, but how wuld you
go about handling it if the application is already running?
Display a message or bring the current running application to
the fore?
Bringing the application to the fore
The easiest and most robust way, is to use a simple IPC
implementation to do the hard work for you. It allows the
running process to be prompted to do something.
//this is a simple interface that provides a stub of the
object
publicinterfaceISharedAssemblyInterface{
int
ShowWindow();
}
//this is an implementation of the interface
public
classAppRemotable: MarshalByRefObject,SharedAssemblyInterface
{
andpublic
AppRemotable(){
and}
andpublic
intShowWindow(){
and//Link toanda static reference of our
main app window and show
andStaticWindow.Show();
and}
}
//this will start off the IPC Server ready for use
staticvoidIPCStart()
{
//IPC port name
IpcChannel
ipcCh = newIpcChannel("AppIPC");
ChannelServices
.RegisterChannel(ipcCh);
RemotingConfiguration
.RegisterWellKnownServiceType
(
typeof(AppRemotable),
"Launch"
,
WellKnownObjectMode
.SingleCall);
}
and
//static function which calls on the running Application to
bring its main window to fore.
staticvoidBringToFore()
{
IpcChannel
ipcCh = newIpcChannel("myClient");
ChannelServices
.RegisterChannel(ipcCh);
ISharedAssemblyInterface
obj =
(
ISharedAssemblyInterface)Activator.GetObject
(
typeof(ISharedAssemblyInterface),"ipc://AppIPC/Launch"
);
obj.ShowWindow();
}
and
We also have to modify the main to use the IPC Mechanism:
bool
test;
System.Threading.
Mutexm = newSystem.Threading.Mutex(true, "app", outtest);
if
(!test){
BringToFore();
return;
}else{
IPCStart();
//Launch application now
}
GC
.KeepAlive(m);
This should provide a robust way of making sure a single
instance of an application is running.
and