5 using System;
6 using System.Configuration;
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.Net;
10 using System.Net.Sockets;
11 using System.Reflection;
12 using System.Runtime.InteropServices;
13 using System.Windows;
14
15 namespace WpfDemo
16 {
17 /// <summary>
18 /// App.xaml 的交互逻辑
19 /// </summary>
20 public partial class App : Application
21 {
22 private LoginWindow login = new LoginWindow();
23 private ILog logger;
24
25 static App()
26 {
27 log4net.Config.XmlConfigurator.Configure();
28 }
29
30 public App()
31 {
32 logger = LogManager.GetLogger(typeof(this));
33 }
34
35 System.Threading.Mutex _mutex;
36 protected override void OnStartup(StartupEventArgs e)
37 {
38 Assembly assembly = Assembly.GetExecutingAssembly();
39 string mutexName = string.Format(CultureInfo.InvariantCulture, "Local\\{{{0}}}{{{1}}}", assembly.GetType().GUID, assembly.GetName().Name);
40 bool ret = false;
41 _mutex = new System.Threading.Mutex(true, mutexName, out ret);
42 if (!ret)
43 {
44 this.logger.Info("已经运行程序,激活至主窗口.");
45 HandleRunningInstance();
46 Environment.Exit(0);
47 return;
48 }
49
50 base.OnStartup(e);
51 this.logger.Info("App startup.");
52 this.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
53
54 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
55 this.DispatcherUnhandledException += App_DispatcherUnhandledException;
56
57 this.login.Show();
58 }
59
60 void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
61 {
62 try
63 {
64 var exception = e.ExceptionObject as Exception;
65 if (exception != null)
66 {
67 this.logger.FatalFormat("非UI线程全局异常, Message:{0}, Error: {1}", exception.Message, exception.ToString());
68 }
69 }
70 catch (Exception ex)
71 {
72 this.logger.FatalFormat("非UI线程全局异常, Message:{0}, Error: {1}", ex.Message, ex.ToString());
73 }
74 }
75
76 void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
77 {
78 try
79 {
80 e.Handled = true;
81 this.logger.FatalFormat("UI线程全局异常:Meassage:{0}, Error: {1}", e.Exception.Message, e.Exception.ToString());
82 }
83 catch (Exception ex)
84 {
85 this.logger.FatalFormat("UI线程全局异常:Meassage:{0}, Error: {1}", ex.Message, ex.ToString());
86 }
87 }
88
89
90 protected override void OnExit(ExitEventArgs e)
91 {
92 this.logger.Info("App exit.");
93
94 base.OnExit(e);
95 }
96
97 ///<summary>
98 /// 该函数设置由不同线程产生的窗口的显示状态
99 /// </summary>
100 /// <param name="hWnd">窗口句柄</param>
101 /// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
102 /// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
103 [DllImport("User32.dll")]
104 private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
105
106 /// <summary>
107 /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
108 /// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
109 /// </summary>
110 /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
111 /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
112 [DllImport("User32.dll")]
113 private static extern bool SetForegroundWindow(IntPtr hWnd);
114
115 static Process RunningInstance()
116 {
117 Process current = Process.GetCurrentProcess();
118 Process[] processes = Process.GetProcessesByName(current.ProcessName);
119 foreach (Process process in processes)
120 {
121 if (process.Id != current.Id)
122 {
123 if (process.MainModule.FileName == current.MainModule.FileName)
124 {
125 return process;
126 }
127 }
128 }
129 return null;
130 }
131
132 private const int SW_NORMAL = 1; //正常弹出窗体
133 private const int SW_MAXIMIZE = 3; //最大化弹出窗体
134
135 public static void HandleRunningInstance()
136 {
137 var instance = RunningInstance();
138 if (instance != null)
139 {
140 ShowWindowAsync(instance.MainWindowHandle, SW_NORMAL);
141 SetForegroundWindow(instance.MainWindowHandle);
142 }
143 }
144 }
145 }