C# 主窗口 单例 唯一进程 互斥锁
用第一个就行
using Microsoft.VisualBasic.ApplicationServices;namespace EngineEMS {internal static class Program {/// <summary>/// 应用程序的主入口点/// </summary>[STAThread]private static void Main() {ApplicationConfiguration.Initialize();// 使用单实例管理器var singleInstanceManager = new SingleInstanceManager();singleInstanceManager.Run(Environment.GetCommandLineArgs());}}// 单实例应用程序管理器public class SingleInstanceManager : WindowsFormsApplicationBase {private MainForm _mainForm;public SingleInstanceManager() {// 启用单实例应用IsSingleInstance = true;}// 当创建新实例时执行protected override void OnCreateMainForm() {_mainForm = new MainForm();MainForm = _mainForm;}// 当检测到已有实例时执行protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) {base.OnStartupNextInstance(eventArgs);// 激活已存在的主窗口if (MainForm != null) {MainForm.WindowState = FormWindowState.Maximized; // 确保窗口最大化MainForm.Activate(); // 激活窗口MainForm.BringToFront();// 前置窗口MainForm.Focus(); // 设置焦点}}}
}
using System;
using System.IO.Pipes;
using System.Threading;
using System.Windows.Forms;namespace EngineEMS {internal static class Program {// 应用程序唯一标识(建议生成新的GUID)private static readonly string UniqueAppId = $"{{AFC5ASE5-LGHJ-4D5C-9A5A-CNNO20010810}}";private static readonly string PipeName = $"EngineEMS_{UniqueAppId}";private static MainForm _mainForm;/// <summary>/// 应用程序的主入口点/// </summary>[STAThread]private static void Main() {using var mutex = new Mutex(true, UniqueAppId, out bool isNewInstance);if (!isNewInstance) {// 不是第一个实例,通过管道通知第一个实例激活窗口NotifyFirstInstance();return;}try {// 第一个实例,启动管道服务器监听新实例StartPipeServer();// 正常启动应用程序ApplicationConfiguration.Initialize();_mainForm = new MainForm();Application.Run(_mainForm);} finally {// 释放互斥体mutex.ReleaseMutex();}}/// <summary>/// 启动命名管道服务器,监听新实例的激活请求/// </summary>private static void StartPipeServer() {var thread = new Thread(PipeServerLoop) {IsBackground = true,Name = "PipeServerThread"};thread.Start();}/// <summary>/// 管道服务器循环,持续监听新实例/// </summary>private static void PipeServerLoop() {while (true) {try {using var pipeServer = new NamedPipeServerStream(PipeName,PipeDirection.In,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);// 等待客户端连接pipeServer.WaitForConnection();// 收到连接,激活主窗口_mainForm?.Invoke((Action)ActivateMainWindow);} catch (Exception ex) {// 记录错误但不中断循环Console.WriteLine($"管道服务器错误: {ex.Message}");Thread.Sleep(1000); // 避免错误时CPU占用过高}}}/// <summary>/// 激活主窗口/// </summary>private static void ActivateMainWindow() {if (_mainForm == null) return;// 恢复窗口(如果最小化)if (_mainForm.WindowState == FormWindowState.Minimized) {_mainForm.WindowState = FormWindowState.Maximized;}// 激活并前置窗口_mainForm.ShowInTaskbar = true;_mainForm.Activate();_mainForm.BringToFront();_mainForm.Focus();}/// <summary>/// 通知第一个实例激活窗口/// </summary>private static void NotifyFirstInstance() {try {using var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.Out);pipeClient.Connect(1000); // 1秒超时// 连接成功即表示通知已发送,无需实际写入数据} catch (TimeoutException) {MessageBox.Show("程序已在运行中,但无法连接到现有实例。","程序已运行",MessageBoxButtons.OK,MessageBoxIcon.Information);} catch (Exception ex) {MessageBox.Show($"程序已在运行中,但发送激活请求时出错:{ex.Message}","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);}}}
}
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;namespace EngineEMS {internal static class Program {/// <summary>/// 应用程序的主入口点/// </summary>[STAThread]private static void Main() {ApplicationConfiguration.Initialize();// 使用单实例管理器var singleInstanceManager = new SingleInstanceManager();singleInstanceManager.Run(Environment.GetCommandLineArgs());}}// 单实例应用程序管理器public class SingleInstanceManager : WindowsFormsApplicationBase {private MainForm _mainForm;public SingleInstanceManager() {// 启用单实例应用IsSingleInstance = true;}// 当创建新实例时执行protected override void OnCreateMainForm() {_mainForm = new MainForm();MainForm = _mainForm;}// 当检测到已有实例时执行protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) {base.OnStartupNextInstance(eventArgs);// 激活已存在的主窗口if (MainForm != null) {// 恢复窗口(如果最小化)if (MainForm.WindowState == FormWindowState.Minimized) {MainForm.WindowState = FormWindowState.Normal;}// 激活并前置窗口MainForm.Activate();MainForm.BringToFront();MainForm.Focus();}// 处理新实例传递的命令行参数if (eventArgs.CommandLine.Count > 0) {// 可以在这里将命令行参数传递给主窗口处理// _mainForm.ProcessCommandLineArgs(eventArgs.CommandLine);}}}
}