原文地址 :http://www.cnblogs.com/emanlee/archive/2009/08/31/1557379.html
using System; using System.Threading; using System.Collections.Generic; using System.Windows.Forms; namespace ArresterSerialPort { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Boolean createdNew; //返回是否赋予了使用线程的互斥体初始所属权 System.Threading.Mutex instance = new System.Threading.Mutex(true, "ArresterSerialPort", out createdNew); //同步基元变量 if (createdNew) //赋予了线程初始所属权,也就是首次使用互斥体 { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); instance.ReleaseMutex(); } else { MessageBox.Show("已经启动了一个程序,请先退出", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new ArresterMainForm()); } } }
防止程序运行多个实例的方法有多种,如:通过使用互斥量和进程名等. 而我想要实现的是:在程序运行多个实例时激活的是第一个实例,使其获得焦点,并在前端显示. 主要调用两个API函数: #region API函数 /// <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 SW_HIDE = 0; //隐藏 private const int SW_SHOWNORMAL = 1; //Normal private const int SW_SHOWMINIMIZED = 2; //最小化 private const int SW_SHOWMAXIMIZED = 3; //最大化 private const int SW_SHOWNOACTIVATE = 4; //激活 private const int SW_RESTORE = 9; //Restore private const int SW_SHOWDEFAULT = 10; //Default #endregion #region 封装API函数 private static void HandleRunningInstance(Process instance) { // 确保窗口没有被最小化或最大化 ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOACTIVATE); // 设置真实例程为foreground window SetForegroundWindow(instance.MainWindowHandle);// 放到最前端 } private static Process RunningInstance() { Process current = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(current.ProcessName); foreach (Process process in processes) { if (process.Id != current.Id) { // 确保例程从EXE文件运行 if (Assembly.GetExecutingAssembly().Location.Replace("/", "\") == current.MainModule.FileName) { return process; } } } return null; } #endregion 以下是在Program.cs类如何调用: /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { try { Process instance = RunningInstance(); if (instance == null) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm); } else { HandleRunningInstance(instance); } catch(Exception e){} }