C# - WinFrm应用程序MessageBox自动关闭小实验
概述
在程序中MessageBox弹出的对话框,用于向用户展示消息,这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。但是有时候在自动化程序中,如果弹出对话框,程序将会中断,等待人工的干预,这是一个非常不好的交互体验,如果程序能够自动帮我们点击其中一个按钮,让对话框消失,该有多好。
原理
通过对话框的标题查找对话框,获取对话框的句柄,然后对话框发送指令。
涉及知识点
- MessageBox 显示消息窗口(也称为对话框)向用户展示消息。这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。System.Windows.Forms.MessageBox可包含通知并指示用户的文本、按钮和符号。
- Thread 创建和控制线程,设置其优先级并获取其状态。本例子主要创建一个线程,查找弹出的窗口。
- WIN32 API 也就是Microsoft Windows 32位平台的应用程序编程接口。每一个服务,就是一个函数,用于和Windows进行交互。
- MessageBoxButtons 是一个Enum,表示对话框上显示哪些按钮。
- PostMessage 是Windows API(应用程序接口)中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessage和PeekMessage取得。
程序运行效果

核心代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace MessageBoxTest
{
/// <summary>
/// 作者:Alan.hsiang
/// 日期:2018-04-18
/// 描述:通过WinAPI进行查找窗口,并对窗口进行操作
/// </summary>
public class MessageBoxHelper
{
/// <summary>
/// 查找窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="title">窗口标题</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(IntPtr hwnd, string title); /// <summary>
/// 移动窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
/// <param name="nWidth">窗口宽度</param>
/// <param name="nHeight">窗口高度</param>
/// <param name="rePaint">是否重绘</param>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool rePaint); /// <summary>
/// 获取窗口矩形
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="rect"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect); /// <summary>
/// 向窗口发送信息
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="msg">信息</param>
/// <param name="wParam">高字节</param>
/// <param name="lParam">低字节</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam); public const int WM_CLOSE = 0x10; //关闭命令 public const int WM_KEYDOWN = 0x0100;//按下键 public const int WM_KEYUP = 0x0101;//按键起来 public const int VK_RETURN = 0x0D;//回车键 public static bool IsWorking = false; /// <summary>
/// 对话框标题
/// </summary>
public static string[] titles = new string[] { "请选择", "提示", "错误", "警告" }; /// <summary>
/// 查找和移动窗口
/// </summary>
/// <param name="title">窗口标题</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
public static void FindAndMoveWindow(string title, int x, int y)
{
Thread t = new Thread(() =>
{
IntPtr msgBox = IntPtr.Zero;
while ((msgBox = FindWindow(IntPtr.Zero, title)) == IntPtr.Zero) ;
Rectangle r = new Rectangle();
GetWindowRect(msgBox, out r);
MoveWindow(msgBox, x, y, r.Width - r.X, r.Height - r.Y, true);
});
t.Start();
} /// <summary>
/// 查找和关闭窗口
/// </summary>
/// <param name="title">标题</param>
private static void FindAndKillWindow(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
int ret = PostMessage(ptr, WM_CLOSE, , );
Thread.Sleep();
ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, );
PostMessage(ptr, WM_KEYUP, VK_RETURN, );
}
}
} /// <summary>
/// 查找和关闭窗口
/// </summary>
public static void FindAndKillWindow()
{
Thread t = new Thread(() =>
{
while (IsWorking)
{
//按标题查找
foreach (string title in titles)
{
FindAndKillWindow(title);
}
Thread.Sleep();
}
}); t.Start();
}
}
}
原博客地址:

C# - WinFrm应用程序MessageBox自动关闭小实验的更多相关文章
- 1.4 Crack小实验
0_day 第一章 基础知识 1.4 Crack小实验 <0day_2th>王清 著 电子书 下载链接:https://pan.baidu.com/s/11TgibQSC3-kYwCInm ...
- Hadoop之词频统计小实验
声明: 1)本文由我原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Ubuntu操作系统,hadoop1-2-1,jdk1.8.0. 3)统计词频工作在单节点的伪分布上,至于真正实 ...
- 秒懂JVM的三大参数类型,就靠这十个小实验了
秒懂JVM的三大参数类型,就靠这十个小实验了 你好,我是悟空哥,「7年项目开发经验,全栈工程师,开发组长,超喜欢图解编程底层原理」.手写了2个小程序,Java刷题小程序,PMP刷题小程序,已发布到公众 ...
- 基于 Source Generators 做个 AOP 静态编织小实验
0. 前言 上接:用 Roslyn 做个 JIT 的 AOP 作为第二篇,我们基于Source Generators做个AOP静态编织小实验. 内容安排如下: source generators 是什 ...
- PBR综合小实验视频-狮子XL
这个是上学时候录的一个策略路由小实验
- ubuntu下格式化内存当硬盘使的小实验
内存虚拟硬盘(ramdisk)是指通过软件技术,将物理内存进行分割,将一部分内存通过虚拟技术转变为硬盘以较大幅度提升计算机数据读取速度和保护硬盘. 在ubuntu下的dev下有ram相关的文件,这些文 ...
- MongoDB 主从复制小实验
MongoDB 主从复制小实验 操作环境描述:WIN8 64位操作系统,内装虚拟机为CentOS 5.5 32位系统. 操作描述:跟其他关系型数据库类似,在主库进行数据操作,将数据同步到从节点,从节 ...
- 张小龙的野心:用小程序重构web|小程序好处及可能的不足
一:张小龙的野心:用小程序重构web 一 很多年以前,张小龙写了一款软件:Foxmail. 这款软件当年有数百万用户,这是一个相当庞大的量,因为彼时网民也只有千万当量级的规模. 我是一个非常忠实的用户 ...
- PS小实验-去除水印
PS小实验-去除水印 水印是一些品牌商覆盖在图片或视频上的一个商标logo或小文本,比如大家最讨厌的百度logo,作者本人也是比较讨厌水印的,让好端端的一张图片变得美中不足. 个人觉得用photosh ...
随机推荐
- ubuntu 18.04多应用窗口切换的快捷键使用指南
前记 使用ubuntu时间长了,很厌烦用鼠标来点来点去.重复操作的,还是快捷键比较方便.在多窗口切换方面,熟悉了几个快捷键之后,顿时感觉神清气爽.这里就推荐给大家学习一下,提高工作效率啊. 常用快捷键 ...
- opencv加载图片imread失败的原因
用简单的imshow函数加载图片,报加载失败的异常,显示没有将图片加载到内存中.原因是在配置环境是同时将*lib与*d.lib都入了附加依赖项,而项目的生成方式选择的是debug,*lib在*d.li ...
- PhantomJS抓取中文文档乱码
使用PhantomJs抓取百度标题乱码 var url="http://www.baidu.com" var page=require('webpage').create() pa ...
- 爬虫selenium中动作链接ActionChains
一.基本语法 生成一个动作actions=ActionChains(driver) 动作添加方法actions.方法 执行 actions.perform() 二.方法列表 click(on_elem ...
- 设计好的报表是如何在 web 上显示的
润乾报表主要用来开发在 java web 端呈现的报表工具,设计器为桌面版,那么开发后的报表如何发布到 web 端是用户较为关心的问题. 润乾报表 web 端发布,采用 Taglib 方式,只需要在 ...
- Cesium专栏-热力图(附源码下载)
Cesium Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精 ...
- 地图SDK全面升级 – 数十项新功能及优化等你来体验
腾讯位置服务地图SDK是一套提供多种地理位置服务的应用程序接口.通过调用该接口,开发者可以在自己的应用中加入地图相关的功能(如地图展示.标注.绘制图形等),轻松访问腾讯地图服务和数据,构建功能丰富.交 ...
- 037.[转] springboot 配置多个数据源
1.在application.properties文件 配置两个数据源 #默认使用 tomcat-jdbc spring.datasource.type=org.apache.tomcat.jdbc. ...
- 在Ubuntu上安装Miniconda
在Ubuntu上安装Miniconda Anaconda是一个开源的Python包管理器,而Miniconda则是轻量级的Anaconda 下载地址:https://docs.conda.io/en/ ...
- 如何去除小程序button的边框
小程序button 自带样式,就算用 border:none: background:none ,还是会有一条细的边框 使用:after选择器就可以去除 button::after{ border:n ...