C# 主窗口 单例 唯一进程 互斥锁

用第一个就行

csharp 复制代码
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();       // 设置焦点
            }
        }
    }
}

csharp 复制代码
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);
            }
        }
    }
}
csharp 复制代码
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);
            }
        }
    }
}
相关推荐
Scout-leaf6 小时前
C#摸鱼实录——IoC与DI案例详解
c#
咕白m6258 小时前
使用 C# 在 Excel 中应用多种字体样式
后端·c#
Artech13 小时前
[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF
ai·c#·agent·agent skills·maf
LDR0061 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术1 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园1 天前
C++20 Modules 模块详解
java·开发语言·spring
swordbob1 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享1 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Luminous.1 天前
C语言--day30
c语言·开发语言
何以解忧,唯有..1 天前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang