Reputation: 2872
I'm trying to use the mutex method for only allowing one instance of my app to run. That is - I only want a max of one instance for all users on a machine. I've read through the various other threads on this issue and the solution seems straightforward enough but in testing I can't get my second instance to not run. Here is my code...
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// check that there is only one instance of the control panel running...
bool createdNew = true;
using (Mutex instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew))
{
if (!createdNew)
{
Application.Current.Shutdown();
return;
}
}
base.OnStartup(e);
}
}
Upvotes: 22
Views: 18383
Reputation: 11
I was told to implement this mutex approach on an already developed WPF application that we had. The work around to the problem with using override of the OnStart()
that I found was in
App.g.cs
This file is located in
obj\x86\debug\
and contains the main()
function, so you just simply put this piece of code in your main function.
bool isOnlyInstance = false;
Mutex m = new Mutex(true, @"WpfSingleInstanceApplication", out isOnlyInstance);
if (!isOnlyInstance)
{
MessageBox.Show("Another Instance of the application is already running.",
"Alert",
MessageBoxButton.OK,
MessageBoxImage.Exclamation);
return;
}
GC.KeepAlive(m);
but for this you need to keep the BUILD ACTION
of your app.xaml set to ApplicationDefinition
NOTE: This might not be the best way, since I'm a beginner. (please tell me if there's something I should change)
Upvotes: 1
Reputation: 41
As extension sample:
public static class Extension
{
private static Mutex mutex;
public static bool IsOneTimeLaunch(this Application application, string uniqueName = null)
{
var applicationName = Path.GetFileName(Assembly.GetEntryAssembly().GetName().Name);
uniqueName = uniqueName ?? string.Format("{0}_{1}_{2}",
Environment.MachineName,
Environment.UserName,
applicationName);
application.Exit += (sender, e) => mutex.Dispose();
bool isOneTimeLaunch;
mutex = new Mutex(true, uniqueName, out isOneTimeLaunch);
return isOneTimeLaunch;
}
}
App Class:
protected override void OnStartup(StartupEventArgs e)
{
if (this.IsOneTimeLaunch())
{
base.OnStartup(e);
}
else
{
this.Shutdown();
}
}
Upvotes: 4
Reputation: 7350
I did this from this link just add the given class and a single line in you App.Xaml.cs http://wpfsingleinstance.codeplex.com/
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
WpfSingleInstance.Make(); //added this is the function of that class
base.OnStartup(e);
}
}
Upvotes: 0
Reputation: 323
I can suggest a much cleaner approach that also introduce the useful concept of overriding the Main method in WPF application. Also, if using your solution you take a look at the task manager, you will notice that the new instance actually reach the execution state (you can see a new process created in the list of task) and then suddenly close. The approach proposed in the post that follows will avoid this drawback too. http://blog.clauskonrad.net/2011/04/wpf-how-to-make-your-application-single.html
Upvotes: 1
Reputation: 2872
Here is my new code which has the answer provided by @Willem van Rumpt (and @OJ)...
public partial class App : Application
{
private Mutex _instanceMutex = null;
protected override void OnStartup(StartupEventArgs e)
{
// check that there is only one instance of the control panel running...
bool createdNew;
_instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew);
if (!createdNew)
{
_instanceMutex = null;
Application.Current.Shutdown();
return;
}
base.OnStartup(e);
}
protected override void OnExit(ExitEventArgs e)
{
if(_instanceMutex != null)
_instanceMutex.ReleaseMutex();
base.OnExit(e);
}
}
Upvotes: 34
Reputation: 29401
You're destroying the Mutex immediately after you've created it and tested it. You need to keep the Mutex reference alive for lifetime of your application.
Make the Mutex a member/field of your Application class. Release the mutex when your application shuts down.
Upvotes: 4
Reputation: 6570
You're also disposing the mutex in the same method, so the mutex only lives for the duration of the method. Store the mutex in a static field, and keep it alive for the duration of your application.
Upvotes: 45