App.xaml.cs中的代码每次都差不多,故特地将其整理出来直接复用:
using System;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows; namespace WpfDemo
{
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application
{
private LoginWindow login = new LoginWindow();
private ILog logger; static App()
{
log4net.Config.XmlConfigurator.Configure();
} public App()
{
logger = LogManager.GetLogger(typeof(this));
} System.Threading.Mutex _mutex;
protected override void OnStartup(StartupEventArgs e)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string mutexName = string.Format(CultureInfo.InvariantCulture, "Local\\{{{0}}}{{{1}}}", assembly.GetType().GUID, assembly.GetName().Name);
bool ret = false;
_mutex = new System.Threading.Mutex(true, mutexName, out ret);
if (!ret)
{
this.logger.Info("已经运行程序,激活至主窗口.");
HandleRunningInstance();
Environment.Exit();
return;
} base.OnStartup(e);
this.logger.Info("App startup.");
this.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
this.DispatcherUnhandledException += App_DispatcherUnhandledException; this.login.Show();
} void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
var exception = e.ExceptionObject as Exception;
if (exception != null)
{
this.logger.FatalFormat("非UI线程全局异常, Message:{0}, Error: {1}", exception.Message, exception.ToString());
}
}
catch (Exception ex)
{
this.logger.FatalFormat("非UI线程全局异常, Message:{0}, Error: {1}", ex.Message, ex.ToString());
}
} void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
try
{
e.Handled = true;
this.logger.FatalFormat("UI线程全局异常:Meassage:{0}, Error: {1}", e.Exception.Message, e.Exception.ToString());
}
catch (Exception ex)
{
this.logger.FatalFormat("UI线程全局异常:Meassage:{0}, Error: {1}", ex.Message, ex.ToString());
}
} protected override void OnExit(ExitEventArgs e)
{
this.logger.Info("App exit."); base.OnExit(e);
} ///<summary>
/// 该函数设置由不同线程产生的窗口的显示状态
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); /// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
/// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd); static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
if (process.Id != current.Id)
{
if (process.MainModule.FileName == current.MainModule.FileName)
{
return process;
}
}
}
return null;
} private const int SW_NORMAL = ; //正常弹出窗体
private const int SW_MAXIMIZE = ; //最大化弹出窗体 public static void HandleRunningInstance()
{
var instance = RunningInstance();
if (instance != null)
{
ShowWindowAsync(instance.MainWindowHandle, SW_NORMAL);
SetForegroundWindow(instance.MainWindowHandle);
}
}
}
}