OSDN Git Service

Avoid multiple instances
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Sun, 16 Apr 2017 14:50:57 +0000 (23:50 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sun, 16 Apr 2017 14:50:57 +0000 (23:50 +0900)
BurageSnap/App.xaml.cs
BurageSnap/BurageSnap.csproj
BurageSnap/PreLounch.cs [new file with mode: 0644]

index da77ed2..4ffe0d8 100644 (file)
@@ -10,15 +10,18 @@ namespace BurageSnap
     /// </summary>
     public partial class App
     {
-#if DEBUG
         public App()
         {
+#if DEBUG
             const string lang = "en";
             Thread.CurrentThread.CurrentCulture = new CultureInfo(lang);
             Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
             FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
                 XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
-        }
 #endif
+            if (PreLounch.ProcessAlreadyExists())
+                Shutdown();
+        }
+
     }
 }
\ No newline at end of file
index 722a528..982ae1c 100644 (file)
       <AutoGen>True</AutoGen>
       <DesignTime>True</DesignTime>
     </Compile>
+    <Compile Include="PreLounch.cs" />
     <Compile Include="WindowPicker.cs" />
     <Page Include="ConfirmView.xaml">
       <SubType>Designer</SubType>
diff --git a/BurageSnap/PreLounch.cs b/BurageSnap/PreLounch.cs
new file mode 100644 (file)
index 0000000..50044af
--- /dev/null
@@ -0,0 +1,59 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace BurageSnap
+{
+    public class PreLounch
+    {
+        [DllImport("user32.dll")]
+        private static extern bool SetForegroundWindow(IntPtr hWnd);
+
+        [DllImport("user32.dll")]
+        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
+
+        private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
+
+        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
+        private static extern bool EnumThreadWindows(int dwThreadId, EnumWindowsProc enumProc, IntPtr lParam);
+
+        public static bool ProcessAlreadyExists()
+        {
+            try
+            {
+                var cur = Process.GetCurrentProcess();
+                var process = Process.GetProcessesByName(cur.ProcessName)
+                    .FirstOrDefault(p => cur.Id != p.Id && p.MainModule.FileName == cur.MainModule.FileName);
+                if (process != null)
+                {
+                    ActivateProcessWindow(process);
+                    return true;
+                }
+            }
+            catch (Win32Exception)
+            {
+                /*
+                 * MainModule.FileName can fail by AV software with Win32Exception.
+                */
+            }
+            return false;
+        }
+
+        private static void ActivateProcessWindow(Process process)
+        {
+            var hwnd = process.MainWindowHandle;
+            if (hwnd == IntPtr.Zero) // stored in the system tray
+            {
+                EnumThreadWindows(process.Threads[0].Id, (hWnd, lParam) =>
+                {
+                    hwnd = hWnd;
+                    return false;
+                }, IntPtr.Zero);
+            }
+            ShowWindowAsync(hwnd, 9); // SW_RESTORE
+            SetForegroundWindow(hwnd);
+        }
+    }
+}
\ No newline at end of file