From 75749906b9558b2fec6cdfa4d623eb0f1c7c5d69 Mon Sep 17 00:00:00 2001 From: Razzmatazz Date: Fri, 12 Mar 2021 16:45:45 -0600 Subject: [PATCH] No longer possible to open two instances of app. Second instance will close and original instance will be activated. --- MainWindow.xaml.cs | 92 ++++++++++++++++++++++++++++++++------ Properties/AssemblyInfo.cs | 4 +- ValheimSaveShield.csproj | 3 +- 3 files changed, 82 insertions(+), 17 deletions(-) diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index d79b16f..23730ca 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -16,6 +16,8 @@ using System.Collections.Specialized; using System.Collections; using RazzTools; +using System.Windows.Interop; +using System.Runtime.InteropServices; namespace ValheimSaveShield { @@ -24,8 +26,8 @@ namespace ValheimSaveShield /// public partial class MainWindow : Window { - private static string defaultBackupFolder = $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\AppData\LocalLow\IronGate\Valheim\backups"; - private static string defaultSaveFolder = $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\AppData\LocalLow\IronGate\Valheim"; + private static string DefaultBackupFolder { get { return $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\AppData\LocalLow\IronGate\Valheim\backups"; } } + private static string DefaultSaveFolder { get { return $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\AppData\LocalLow\IronGate\Valheim"; } } private List listBackups; private Boolean suppressLog; private Color defaultTextColor; @@ -38,6 +40,9 @@ public partial class MainWindow : Window private Thread ftpDirectorySync = null; + private readonly Mutex _mutex; + private const string mutexName = "MUTEX_VALHEIMSAVESHIELD"; + private bool IsBackupCurrent { get { foreach (var saveDirPath in Properties.Settings.Default.SaveFolders) @@ -95,15 +100,36 @@ private StringCollection SavePaths ~MainWindow() { + if (notifyIcon != null) + { + notifyIcon.Dispose(); + } if (ftpDirectorySync != null) { ftpDirectorySync.Abort(); } + if (_mutex != null) + { + _mutex.Dispose(); + } } public MainWindow() { InitializeComponent(); + bool firstInstance; + _mutex = new Mutex(true, mutexName, out firstInstance); + if (!firstInstance) + { + NativeMethods.PostMessage( + (IntPtr)NativeMethods.HWND_BROADCAST, + NativeMethods.WM_SHOWME, + IntPtr.Zero, + IntPtr.Zero + ); + Close(); + return; + } suppressLog = false; if (Properties.Settings.Default.CreateLogFile) { @@ -115,8 +141,10 @@ public MainWindow() if (Properties.Settings.Default.UpgradeRequired) { Properties.Settings.Default.Upgrade(); + logMessage($"Previous backup folder: {Properties.Settings.Default.GetPreviousVersion("BackupFolder")}"); Properties.Settings.Default.UpgradeRequired = false; Properties.Settings.Default.Save(); + logMessage($"Current backup folder: {Properties.Settings.Default.BackupFolder}"); } Width = Properties.Settings.Default.MainWindowWidth; Height = Properties.Settings.Default.MainWindowHeight; @@ -150,20 +178,20 @@ public MainWindow() Properties.Settings.Default.WorldFileExtensions = new StringCollection(); Properties.Settings.Default.Save(); } - if (Properties.Settings.Default.BackupFolder.Length == 0) + saveWatchers = new List(); + if (Properties.Settings.Default.BackupFolder == "") { logMessage("Backup folder not set; reverting to default."); - Properties.Settings.Default.BackupFolder = defaultBackupFolder; + Properties.Settings.Default.BackupFolder = DefaultBackupFolder; Properties.Settings.Default.Save(); } - else if (!Directory.Exists(Properties.Settings.Default.BackupFolder) && !Properties.Settings.Default.BackupFolder.Equals(defaultBackupFolder)) + else if (!Directory.Exists(Properties.Settings.Default.BackupFolder) && !Properties.Settings.Default.BackupFolder.Equals(DefaultBackupFolder)) { logMessage($"Backup folder {Properties.Settings.Default.BackupFolder}) not found; reverting to default."); - Properties.Settings.Default.BackupFolder = defaultBackupFolder; + Properties.Settings.Default.BackupFolder = DefaultBackupFolder; Properties.Settings.Default.Save(); } - saveWatchers = new List(); - if (Properties.Settings.Default.SaveFolders != null && Properties.Settings.Default.SaveFolders.Count > 0) + if (Properties.Settings.Default.SaveFolders.Count > 0) { foreach (var path in Properties.Settings.Default.SaveFolders) { @@ -188,12 +216,12 @@ public MainWindow() else { logMessage("Reverting to default save folder."); - lstSaveFolders.Items.Add(defaultSaveFolder); - AddToSaveWatchers(defaultSaveFolder); + lstSaveFolders.Items.Add(DefaultSaveFolder); + AddToSaveWatchers(DefaultSaveFolder); lstSaveFolders.Items.Refresh(); - Properties.Settings.Default.SaveFolders.Add(defaultSaveFolder); - Properties.Settings.Default.FtpSaveDest = defaultSaveFolder; + Properties.Settings.Default.SaveFolders.Add(DefaultSaveFolder); + Properties.Settings.Default.FtpSaveDest = DefaultSaveFolder; Properties.Settings.Default.Save(); } // start the directory syncing if user has the correct settings for it @@ -212,6 +240,35 @@ public MainWindow() notifyIcon.Click += NotifyIcon_Click; storedWindowState = WindowState.Normal; } + //This event is raised to support interoperation with Win32 + protected override void OnSourceInitialized(EventArgs e) + { + base.OnSourceInitialized(e); + HwndSource source = PresentationSource.FromVisual(this) as HwndSource; + source.AddHook(WndProc); + } + //Receive and act on messages + IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + // Handle messages... + if (msg == NativeMethods.WM_SHOWME) + { + Show(); + Activate(); + WindowState = storedWindowState; + } + return IntPtr.Zero; + } + //dll import magic + internal class NativeMethods + { + public const int HWND_BROADCAST = 0xffff; + public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME"); + [DllImport("user32")] + public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); + [DllImport("user32")] + public static extern int RegisterWindowMessage(string message); + } private void SaveWatcher_LogMessage(object sender, SaveWatcherLogMessageEventArgs e) { @@ -244,6 +301,7 @@ private void AddToSaveWatchers(string path) private void NotifyIcon_Click(object sender, EventArgs e) { Show(); + Activate(); WindowState = storedWindowState; } @@ -960,13 +1018,19 @@ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs private void Window_Closed(object sender, EventArgs e) { - notifyIcon.Dispose(); - notifyIcon = null; + if (notifyIcon != null) + { + notifyIcon.Dispose(); + } if (ftpDirectorySync != null) { ftpDirectorySync.Abort(); ftpDirectorySync = null; } + if (_mutex != null) + { + _mutex.Dispose(); + } } private void BtnBackupFolder_Click(object sender, RoutedEventArgs e) diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 2ee4e87..ced5f19 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.4.8.0")] -[assembly: AssemblyFileVersion("0.4.8.0")] +[assembly: AssemblyVersion("0.4.9.0")] +[assembly: AssemblyFileVersion("0.4.9.0")] diff --git a/ValheimSaveShield.csproj b/ValheimSaveShield.csproj index bf97483..e61077b 100644 --- a/ValheimSaveShield.csproj +++ b/ValheimSaveShield.csproj @@ -226,7 +226,8 @@ copy "$(TargetDir)ModernWpf.dll" "$(TargetDir)app.publish\" copy "$(TargetDir)ValheimSaveShield.exe.config" "$(TargetDir)app.publish\" -copy "$(TargetDir)WinSCPnet.dll" "$(TargetDir)app.publish\" +copy "$(TargetDir)WinSCPnet.dll" "$(TargetDir)app.publish\" +if $(ConfigurationName) == Release "C:\Program Files\7-Zip\7z.exe" a %25userprofile%25\Desktop\vss.zip "$(TargetDir)app.publish\*"