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);
            }
        }
    }
}
相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
神仙别闹1 天前
基于C#+MySQL实现(WinForm)个人聊天室软件
c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
kybs19911 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int1 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
CoderYanger1 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读1 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json