using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace PRSRecordingNotes { /// /// Interaction logic for App.xaml /// public partial class App : Application { #region Constants and Fields /// The event mutex name. private const string UniqueEventName = "27722504-3ECA-4493-A942-DF08FFD92500"; /// The unique mutex name. private const string UniqueMutexName = "65B5069F-33AB-42A1-AB42-3E495097A859"; /// The event wait handle. private EventWaitHandle eventWaitHandle; /// The mutex. private Mutex mutex; #endregion #region Methods /// The app on startup. /// The sender. /// The e. private void AppOnStartup(object sender, StartupEventArgs e) { bool isOwned; this.mutex = new Mutex(true, UniqueMutexName, out isOwned); this.eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName); // So, R# would not give a warning that this variable is not used. GC.KeepAlive(this.mutex); if (isOwned) { // Spawn a thread which will be waiting for our event var thread = new Thread( () => { while (this.eventWaitHandle.WaitOne()) { Current.Dispatcher.BeginInvoke( (Action)(() => ((ScreenRecorderWindow)Current.MainWindow).BringToForeground())); } }); // It is important mark it as background otherwise it will prevent app from exiting. thread.IsBackground = true; thread.Start(); return; } // Notify other instance so it could bring itself to foreground. this.eventWaitHandle.Set(); // Terminate this instance. this.Shutdown(); } #endregion } }