UPDATED
After a lot of poking around on this subject I found a rather neat way of enforcing an application to behave in a single instance manner. I’ve only just started looking at this issue so I can’t vouch for its security at the moment but in light of a few examples I found this seems like a very simple solution.
A few of the examples included a fair amount of coding to achieve the Single Instance behaviour, including removing the App.xaml file altogether, I tried various things but some of the bindings I had setup really didn’t enjoy life after the App.xaml was taken from them.
[source:c-sharp] public partial class App : Application{
public App() : base()
{
System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName);
if (process.Length > 1)
{
MessageBox.Show(“MyApplication is already running …”, “MyApplication Launch”, MessageBoxButton.OK, MessageBoxImage.Information);
this.Shutdown();
}
}
}
[/source]
That is one way of achieving a single instance application. However a far better solution is one that makes use of a Mutex. This is far more robust and definitely the recommended approach for the majority of applications. The code below is a static Main() method inside a WPF App class:
[source:c-sharp] private static bool isNew; [System.STAThreadAttribute()] public static void Main(){
using (Mutex m = new Mutex(true, “ThisIsTheStringMutexValueThatMustBeUnique”, out isNew))
{
if (isNew)
{
MyWPFApplication.App app = new MyWPFApplication.App();
app.InitializeComponent();
app.Run();
}
else
{
MessageBox.Show(“MyWPFApplication is already running!”, “MyWPFApplication”, MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
}
}
}
[/source]
Hello! I am looking at the using the above mentioned code sample. The only thing different that I am doing is that instead of putting it in the constructor, I am overriding the OnStartUp(…) method. I was curious as to what feedback you got about it (security,…) Is this the best way to do this?
Hi,
To be honest, this isn’t the best way of doing it. The best way to achieve this is by using a Mutex. In fact, since you have replied to this I’m going to update this post with a more robust method. Check back in a few hours and I’ll have that included in this post.
Your second way is currently not working, cause there is already method Main generated by Visualstudio.
How do worked around this?
Hi Christopher,
What you need to do is right-click on your App.xaml file in your solution, this will show you the properties for the App.xaml file.
If you look at the first property in the list, called Build Action, change this from “ApplicationDefinition” to “Page”
Hope this helps.
Thx. I found another Way without changing it to page.
public partial class App : Application
{
Mutex mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
//Change Global to Local to allow application to start in different UserSessions on same PC (XP/Vista Quick User Change)
string mutexName = “Global\MyApp.SingleInstance”;
try
{
// Create a new mutex object with a unique name
mutex = new Mutex(false, mutexName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + “nn” + ex.StackTrace +
“nn” + “Application Exiting…”, “Exception thrown”);
Application.Current.Shutdown();
}
if (mutex.WaitOne(0, false))
{
base.OnStartup(e);
}
else
{
MessageBox.Show(“Application already startet.”, “Error”, MessageBoxButton.OK, MessageBoxImage.Information);
Application.Current.Shutdown();
}
}
Jammer: any particular reason why isNew is static instead of local to Main()?
Only if you want to use it outside of the main() method really.
I like Christopher’s approach. But any special reason to use the Mutex.WaitOne method instead of the three argument contructor of Mutex that’s used here:
http://codelog.blogial.com/2009/05/24/creating-a-single-instance-application-in-c-wpf/
More advanced solution: http://blogs.microsoft.co.il/blogs/maxim/archive/2010/02/13/single-instance-application-manager.aspx
Hi Maxim, thanks for this link, nice solution.
In Release Mode its not working