【C#】检查已有窗口,防止重复打开

ops/2025/3/6 3:50:25/

winform项目只允许打开一个窗口
在 WinForms 项目中,如果 希望 程序只允许打开一个主窗口,可以使用 单实例模式,防止用户重复启动应用程序。


✅ 方法 1:检查已有窗口,防止重复打开(推荐)

如果 需求是 防止打开多个同类型窗口,可以在 Program.cs 中检查当前进程是否已有运行的实例。

🔹 代码修改 Program.cs

using System;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;static class Program
{[STAThread]static void Main(){bool isNewInstance;using (Mutex mutex = new Mutex(true, "MyUniqueAppName", out isNewInstance)){if (!isNewInstance){MessageBox.Show("程序已经在运行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);return; // 直接退出,避免打开多个实例}Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new MainForm()); // 启动主窗口}}
}

📌 关键点

  • 使用 Mutex(互斥量) 确保程序只运行一个实例
  • 如果已有实例,弹出提示并退出程序
  • MyUniqueAppName 需替换为你的项目唯一标识

✅ 方法 2:防止主窗口重复打开

如果你只想 限制主窗口只能打开一次,可以在按钮事件里检查是否已经存在实例。

🔹 代码修改

private void btnOpenMainForm_Click(object sender, EventArgs e)
{// 检查是否已有主窗口实例var existingForm = Application.OpenForms["MainForm"];if (existingForm != null){existingForm.BringToFront(); // 如果已存在,让它显示在最前return;}MainForm mainForm = new MainForm();mainForm.Show();
}

📌 关键点

  • 检查 Application.OpenForms 集合,防止重复打开 MainForm
  • 如果已有实例,只让窗口置顶(BringToFront()

🔥 小结

方法适用场景关键技术
方法 1(推荐)整个程序 只允许一个实例Mutex
方法 2只限制某个窗口不能重复打开Application.OpenForms

推荐方法 1,这样即使用户双击 .exe 多次,也不会启动多个进程。

Mutex mutex = new Mutex(true, "MyUniqueAppName", out isNewInstance);
这行代码用于创建一个 互斥体(Mutex),确保程序只能运行一个实例。


补充

🔹 讲解 Mutex 构造函数

Mutex(bool initiallyOwned, string name, out bool createdNew)
参数作用
initiallyOwnedtrue 表示当前线程初始拥有该互斥体
name互斥体的全局唯一名称(多个进程之间共享)
createdNewout 参数,表示是否成功创建新 Mutex 实例(true 说明是新的)

🔹 参数解析

bool isNewInstance;
Mutex mutex = new Mutex(true, "MyUniqueAppName", out isNewInstance);
  1. true当前进程 申请 Mutex 的所有权
  2. "MyUniqueAppName" ➝ Mutex 名称(必须唯一,所有实例共享这个名称)
  3. out isNewInstance是否创建了新 Mutex
    • true:当前进程是第一个拥有该 Mutex 的实例
    • false:Mutex 已存在,说明已有程序在运行

🔹 如何判断程序是否已运行

if (!isNewInstance)
{MessageBox.Show("程序已经在运行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);return; // 直接退出程序
}
  • 如果 isNewInstance == false,说明已有实例在运行,弹出提示,避免打开多个实例。

🔹 关键点

  1. 创建 Mutex,检查是否已有程序运行
  2. 如果 isNewInstance == false,直接退出
  3. 否则,启动 MainForm,并在 using 作用域结束后释放 Mutex

🔥 小结

  • Mutex(互斥体) 用于确保程序只运行一个实例
  • 使用 name 标识(多个程序共享该 Mutex 名称)
  • isNewInstance 返回 false 说明已有实例运行,防止重复启动

http://www.ppmy.cn/ops/163488.html

相关文章

[arXiv 2025]BP-GPT: Auditory Neural Decoding Using fMRI-prompted LLM

论文网址:BP-GPT: Auditory Neural Decoding Using fMRI-prompted LLM 论文代码:https://github.com/1994cxy/BP-GPT 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现…

Ai-web 1.0靶场通关攻略

1.环境 虚拟机:kali 靶机:ai-web-1.0 2.获取靶机ip 确认靶机ip为192.168.13.160 3.获取绝对路径 用御剑扫描发现两个路径 http://192.168.13.160/robots. txt和http://192.168.13.160/index.html 发现一些路径 用kali的dirb扫描发现一个info.php文件…

Spring Cloud Alibaba学习 4- Spring Cloud Gateway入门使用

Spring Cloud Alibaba学习 4- Spring Cloud Gateway入门使用 中文文档Spring Cloud Gateway 中文文档 一. 基本使用 1. Predicate配置 1.1 配置参数介绍 直接通过官方给的application.yml介绍,这里就不介绍简写方式了,直接介绍完整方式 spring:clo…

Jedis、Lettuce和Redisson性能设计

一、Jedis源码级学习要点 1. 线程模型与连接管理 阻塞式I/O设计:通过Socket直接建立连接,每个命令发送后线程会阻塞等待响应25连接池实现:JedisPool管理物理连接,避免线程安全问题,核心类GenericObjectPool实现连接复…

Skynet入门(一)

概念 skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。 设计初衷 如何充分利用它们并行运作数千个相互独立的业务。 模块设计建议 在 skynet 中,用服务 (service) 这…

中科大 计算机网络组成原理 1.4 接入网和物理媒体 笔记

一、接入网核心功能与架构 ‌核心作用‌ 接入网是连接用户终端与核心网络的桥梁,承担用户身份认证、带宽分配、数据加密等功能,直接影响网络服务的可靠性和用户体验。例如,杭州电视台的数字人主播通过光纤专线实现零失误新闻播报,…

Unity插件-Mirror使用方法(五)组件介绍(​Network Identity)

目录 一、插件介绍 二、主要组件 Network Manager Network Manager HUD 三、Network Identity 1、组件介绍 2、核心功能 网络唯一标识 同步生命周期 权限管理 组件依赖 3、关键属性与配置 4、基础使用方法 1. 添加与配置 2. 脚本中的访问 5、高级功能与示例 1…

Arm64架构的Linux服务器安装jdk8

一、下载 JDK8 打开浏览器,访问 oracle官网找到适用于自己服务器的 arm64 架构的 JDK8 安装包。 二、安装 JDK8 将下载好的 JDK 压缩包上传到服务器上 解压 JDK 压缩包: tar -zxvf jdk-8uXXX-linux-arm64.tar.gz选择安装目录,我将 JDK 安装…