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);
            }
        }
    }
}
相关推荐
似水明俊德8 小时前
02-C#.Net-反射-面试题
开发语言·面试·职场和发展·c#·.net
Thera7779 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
炘爚10 小时前
C语言(文件操作)
c语言·开发语言
阿蒙Amon10 小时前
C#常用类库-详解SerialPort
开发语言·c#
凸头10 小时前
CompletableFuture 与 Future 对比与实战示例
java·开发语言
wuqingshun31415910 小时前
线程安全需要保证几个基本特征
java·开发语言·jvm
Moksha26210 小时前
5G、VoNR基本概念
开发语言·5g·php
jzlhll12311 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
W.D.小糊涂11 小时前
gpu服务器安装windows+ubuntu24.04双系统
c语言·开发语言·数据库
用头发抵命11 小时前
Vue 3 中优雅地集成 Video.js 播放器:从组件封装到功能定制
开发语言·javascript·ecmascript