当前位置: 首页 > news >正文

完整教程: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);
}
}
}
}
http://www.rkmt.cn/news/28080.html

相关文章:

  • 2025年粘度计厂家权威推荐榜:在线/旋转/振动/在线振动/在线旋转/实验室旋转/实验室在线/反应釜在线/管线在线振动/实验室振动粘度计专业选购指南
  • 2025 年国内装修公司最新推荐排行榜:聚焦高端定制与环保需求,精选优质品牌供业主参考苏州高端/装修收纳设计/不锈钢橱柜/别墅装修公司推荐
  • Vue每日一题 父子组件通信
  • Laravel项目接入Nacos配置中心完整部署方案
  • Vue每日一题 - Day 1
  • 2025年每个开发者都必须知道的100多个JavaScript术语(附示例)
  • 2025年知名的氮气电加热器,电加热器厂家推荐及选择指南
  • 0264-CLAP-注解验证参数
  • 0260-CLAP-编写测试函数
  • CSDN博客文章批量导出与文件名规范化实战
  • 0257-CLAP-校验参数范围
  • dls
  • 高压电缆生产厂家口碑榜:基于技术实力、客户服务及市场反馈的专业评估
  • 基于TMS320F28034的全桥LLC电源控制
  • 2025年10月ai优化推荐:主流榜单对比与避坑指南
  • QOJ#12181. abc
  • 行业配置策略
  • Kubernetes 主流网络插件的关键差异对比 - 详解
  • dokuwiki制作侧边栏
  • 广义串并联图学习笔记
  • windows启动zookeeper报错Unable to create data directory ..datalversion-2
  • 资源分享--豪氏象棋教程
  • 第08周 预习、实验及作业:Java GUI编程
  • redis-Sentinel
  • 【A】Sakura Tears
  • Datawhale 春训营新能源预测(数据处理)
  • AI股票预测分析报告 - 2025年10月23日
  • 2025年10月deepseek排名优化推荐:主流机构对比排行榜
  • 异常值检测算法学习
  • 取方案