在App.xaml.cs中
'''
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Windows;
namespace DocumentAnalysisTool
{
///
/// App.xaml 的交互逻辑
///
public partial class App : Application
{
//System.Threading.Mutex mutex;
//防止程序运行多个实例的方法有多种,如:通过使用互斥量和进程名等.而我想要实现的是:在程序运行多个实例时激活的是第一个实例,使其获得焦点,并在前端显示.
//主要用到两个API 函数:
//ShowWindowAsync 该函数设置由不同线程产生的窗口的显示状态。
//SetForegroundWindow 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// <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);
//private const int WS_SHOWNORMAL = 1;
public App()
{
Startup += new StartupEventHandler(App_Startup);
}
private void App_Startup(object sender, StartupEventArgs e)
{
//bool ret;
//mutex = new System.Threading.Mutex(true, "ElectronicNeedleTherapySystem", out ret);
//if (!ret)
//{
// Environment.Exit(0);
//}
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
Process instance = RunningInstance();
if (instance != null)
{
HandleRunningInstance(instance);
Environment.Exit(0);
}
}
/// <summary>
/// 获取正在运行的实例,没有运行的实例返回null;
/// </summary>
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
if (process.Id != current.Id)
{
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
{
return process;
}
}
}
return null;
}
/// <summary>
/// 显示已运行的程序。
/// </summary>
public void HandleRunningInstance(Process instance)
{
//MessageBox.Show("ID:"+instance.Id .ToString()+"--句柄"+instance.MainWindowHandle.ToString() + "--正常窗口" + WS_SHOWNORMAL + "--" + ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL) + "--" + SetForegroundWindow(instance.MainWindowHandle));
//ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //显示,可以注释掉
SetForegroundWindow(instance.MainWindowHandle); //放到前端
}
///// <summary>
///// 检查是否是管理员身份
///// </summary>
//private void CheckAdministrator()
//{
// var wi = WindowsIdentity.GetCurrent();
// var wp = new WindowsPrincipal(wi);
// bool runAsAdmin = wp.IsInRole(WindowsBuiltInRole.Administrator);
// if (!runAsAdmin)
// {
// // It is not possible to launch a ClickOnce app as administrator directly,
// // so instead we launch the app as administrator in a new process.
// var processInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().CodeBase);
// // The following properties run the new process as administrator
// processInfo.UseShellExecute = true;
// processInfo.Verb = "runas";
// // Start the new process
// try
// {
// Process.Start(processInfo);
// }
// catch (Exception)
// {
// //ex.WriteLog();
// }
// // Shut down the current process
// Environment.Exit(0);
// }
//}
//protected override void OnStartup(StartupEventArgs e)
//{
// base.OnStartup(e);
// CheckAdministrator();
// //如果不是管理员,程序会直接退出,并使用管理员身份重新运行。
// StartupUri = new Uri("MainWindow.xaml", UriKind.RelativeOrAbsolute);
//}
}
}
'''