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);
            }
        }
    }
}
相关推荐
北冥湖畔的燕雀2 小时前
C++泛型编程(函数模板以及类模板)
开发语言·c++
QX_hao3 小时前
【Go】--map和struct数据类型
开发语言·后端·golang
你好,我叫C小白3 小时前
C语言 循环结构(1)
c语言·开发语言·算法·while·do...while
Evand J5 小时前
【MATLAB例程】基于USBL和DVL的线性回归误差补偿,对USBL和DVL导航数据进行相互补偿,提高定位精度,附代码下载链接
开发语言·matlab·线性回归·水下定位·usbl·dvl
爱喝白开水a6 小时前
LangChain 基础系列之 Prompt 工程详解:从设计原理到实战模板_langchain prompt
开发语言·数据库·人工智能·python·langchain·prompt·知识图谱
Neverfadeaway6 小时前
【C语言】深入理解函数指针数组应用(4)
c语言·开发语言·算法·回调函数·转移表·c语言实现计算器
武子康6 小时前
Java-152 深入浅出 MongoDB 索引详解 从 MongoDB B-树 到 MySQL B+树 索引机制、数据结构与应用场景的全面对比分析
java·开发语言·数据库·sql·mongodb·性能优化·nosql
杰克尼6 小时前
JavaWeb_p165部门管理
java·开发语言·前端
一成码农6 小时前
JavaSE面向对象(下)
java·开发语言
偶尔的鼠标人7 小时前
Avalonia DataGrid 控件的LostFocus事件会多次触发
开发语言·c#