WPF-禁止二次启动
App.xaml.cs
1 protected override void OnStartup(StartupEventArgs e) 2 { 3 //禁止二次启动 4 this.Startup += new StartupEventHandler(App_Startup); 5 base.OnStartup(e); 6 } 7 #region 禁止二次启动 8 // 用于激活已打开的窗体 9 [DllImport("user32.dll")] 10 public static extern void SetForegroundWindow(IntPtr hwnd); 11 //操作当前窗体 12 //nCmdShow: 0关闭窗口/1正常大小显示窗口/2最小化窗口/3最大化窗口 13 [DllImport("user32.dll")] 14 public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); 15 16 System.Threading.Mutex mutex; 17 void App_Startup(object sender, StartupEventArgs e) 18 { 19 bool ret; 20 mutex = new System.Threading.Mutex(true, "WpfDemo", out ret); 21 if (!ret) 22 { 23 System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("WpfDemo"); 24 foreach (System.Diagnostics.Process p in proc) 25 { 26 SetForegroundWindow(p.MainWindowHandle); 27 ShowWindow(p.MainWindowHandle, 1); 28 NoSecond.SendMessage(p.MainWindowHandle); 29 } 30 Environment.Exit(0); 31 } 32 } 33 #endregion
NoSecond.cs
1 /// <summary> 2 /// 禁止程序二次启动 3 /// </summary> 4 public class WPFNoSecond 5 { 6 public const int NoSecond_DATA = 0x004A; 7 [DllImport("User32.dll", EntryPoint = "SendMessage")] 8 private static extern int SendMessage 9 ( 10 IntPtr hWnd, //目标窗体句柄 11 int Msg, //WM_COPYDATA 12 int wParam, //自定义数值 13 ref CopyDataStruct lParam //结构体 14 ); 15 [StructLayout(LayoutKind.Sequential)] 16 public struct CopyDataStruct 17 { 18 public IntPtr dwData; 19 public int cbData;//字符串长度 20 [MarshalAs(UnmanagedType.LPStr)] 21 public string lpData;//字符串 22 } 23 24 public static void SendMessage(IntPtr thisIntPtr) 25 { 26 IntPtr xmlIntPt = new IntPtr(GetIntPtr()); 27 if (xmlIntPt != IntPtr.Zero || thisIntPtr != IntPtr.Zero) 28 { 29 CopyDataStruct cds; 30 cds.dwData = IntPtr.Zero; 31 cds.lpData = "0123"; 32 cds.cbData = 4;//注意:长度为字节数 33 int fromWindowHandler = 0;// 消息来源窗体 34 SendMessage(thisIntPtr.ToInt32() == 0 ? xmlIntPt : thisIntPtr, NoSecond_DATA, fromWindowHandler, ref cds); 35 } 36 } 37 38 #region 窗体句柄指针 39 static string _IntPtrDataDic = AppDomain.CurrentDomain.BaseDirectory + "/XML/"; 40 static string _IntPtrDataName = "Data.xml"; 41 static void intPtrDataExists() 42 { 43 try 44 { 45 if (!System.IO.File.Exists(_IntPtrDataDic)) 46 { 47 if (!Directory.Exists(_IntPtrDataDic)) { Directory.CreateDirectory(_IntPtrDataDic); } 48 XmlDocument doc = new XmlDocument(); 49 doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", "")); 50 XmlElement root = doc.CreateElement("Root"); 51 root.InnerText = "0"; 52 doc.AppendChild(root); 53 doc.Save(_IntPtrDataDic); 54 } 55 } 56 catch (Exception) { } 57 } 58 static int GetIntPtr() 59 { 60 intPtrDataExists(); 61 XDocument xml = XDocument.Load(_IntPtrDataDic + _IntPtrDataName); 62 XElement xmlRoot = xml.Root; 63 return Convert.ToInt32(xmlRoot.Value); 64 } 65 public static void SetIntPtr(string intPtr) 66 { 67 intPtrDataExists(); 68 XDocument xml = XDocument.Load(_IntPtrDataDic + _IntPtrDataName); 69 XElement xmlRoot = xml.Root; 70 xmlRoot.Value = intPtr; 71 xml.Save(_IntPtrDataDic + _IntPtrDataName); 72 } 73 #endregion 74 }
Window.cs
1 #region 禁止二次启动 2 private void Window_SourceInitialized(object sender, EventArgs e) 3 { 4 HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 5 if (source == null) { throw new Exception("Cannot get HwndSource instance."); } 6 source.AddHook(new HwndSourceHook(this.WndProc)); 7 } 8 private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 9 { 10 try 11 { 12 switch (msg) 13 { 14 case WPFNoSecond.NoSecond_DATA: 15 this.Show(); 16 break; 17 } 18 } 19 catch (Exception) { } 20 return IntPtr.Zero; 21 } 22 #endregion 23 //最小化到托盘 24 private void Window_Min(object sender, RoutedEventArgs e) 25 { 26 //存储当前窗体句柄 27 WPFNoSecond.SetIntPtr(new WindowInteropHelper(this).Handle.ToString()); 28 }
如果现在不努力,以后会活的更累吧。