I often write .net applications that only support one instance. Formerly I used .net-remoting and now WCF to detect if already an instance of my app is running and giving th
The traditional way to do this is with a mutex, e.g.
bool bNew = true;
using (Mutex mutex = new Mutex(true, "MYAPP_0D36E4C9-399D-4b05-BDA3-EE059FB77E8D", out bNew))
{
if (bNew)
{
// blah, blah,
Application.Run(new MainForm());
}
}
Edit:
I found this code to invoke SetForegroundWindow online, so you can find the other instance of your app and bring it forward:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
Process me = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName (me.ProcessName))
{
if (process.Id != me.Id)
{
SetForegroundWindow (process.MainWindowHandle);
break;
}
}
Note that in modern Windows implementations you can only give the foreground away.
I would suggest Singleton-Pattern. Look at this (example for VB.net!):http://vbnotebookfor.net/2007/09/13/introduction-to-the-singleton-pattern-in-vbnet/
Greetz
I use a Mutex, and FindWindow to do this.
Concerning your comment on another answer:
For information on Local and Global mutexes in Terminal Services, follow this link.
Terminal Services client processes can use object names with a "Global\" or "Local\" prefix to explicitly create an object in the global or session name space.
This is the code I use to activate the window:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SH_SHOW = 5;
private const int SH_RESTORE = 9;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public void Activate(IntPtr hwnd)
{
if (IsIconic(hwnd))
ShowWindow(hwnd, SH_RESTORE);
else
ShowWindow(hwnd, SH_SHOW);
SetForegroundWindow(hwnd);
}
There's a simpler way - with help of WindowsFormsApplicationBase class from Microsoft.VisualBasic.ApplicationServices:
using System;
using System.Collections.Generic;
public class SingleInstanceApplicationWrapper :
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
public SingleInstanceApplicationWrapper()
{
IsSingleInstance = true;
}
private MyApp m_app;
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// here we create our WPF application
m_app = new MyApp();
m_app.Run();
return false;
}
protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
{
m_app.DispatchCommandLineParams(e.CommandLine);
}
}
public class MyApp : System.Windows.Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
DispatchCommandLineParams(e.Args);
}
public void DispatchCommandLineParams(IEnumerable<string> cmdParams)
{
// process command line parameters
Console.WriteLine(this.GetHashCode() + " - dispatched");
}
}
public class Program
{
[STAThread]
public static void Main(string[] args)
{
var wrapper = new SingleInstanceApplicationWrapper();
wrapper.Run(args);
}
}