当前位置: 首页 > 编程日记 > 正文

C#用 SendKyes 结合 Process 或 API FindWindow、SendMessage(PostMessage) 等控制外部程序

  • Win32 平台是 消息驱动模式
  • .Net 框架是 事件驱动模式
  • 标题所指的 “控制外部程序”,外部程序是指与本程序无内在相关性的另外一个程序

基于上面提到的,对于.NET的winform程序,在默认情况下(即未对接收消息的事件做自定义处理,说白了:就是没有 重写/覆写(override)窗体(Form)的DefWndProc 事件),.Net 的 winform 程序,是不响应所接收到的自定义消息的。

我们这里要讨论的内容,就分为两种情况:

  1. C#/.NET的程序,控制外部的 win32程序(win16不做考虑)
  2. C#/.NET的程序,控制外部的 .NET程序

从标题,大家也看到, C# 对外部程序的控制, 我们也分为两种情况来讨论:

  1. .NET 平台自带的 SendKeys 和 Process 结合的方式
  2. 完全利用 Windows API 的消息机制 的方式

一、.NET平台自带的 Process 和 SendKeys 结合的方式

本例子,用 C# 的一个Winform程序,创建一个指定路径的文本文件,写入某些内容后,并保存。

为了看清效果,将 Form 的 TopMost 设为 true

bh

  private void button1_Click( object sender, EventArgs e )
{
//启动notepad.exe 记事本程序,并在d:\下创建 或 打开 text_test.txt文件
System.Diagnostics.Process txt = System.Diagnostics.Process.Start ( @"notepad.exe", @"d:\text_test.txt" );
txt.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
//等待一秒,以便目标程序notepad.exe输入状态就绪
txt.WaitForInputIdle ( 1000 );
//如果目标程序 notepad.exe 没有停止响应,则继续
if ( txt.Responding )
{
//开始写入内容
SendKeys.SendWait ( "-----下面的内容是外部程序自动写入-----\r\n" );
SendKeys.SendWait ( this.textBox1.Text );     //将文本框内的内容写入
SendKeys.SendWait ( "{Enter}{Enter}" );     //写入2个回车
SendKeys.SendWait ( "文档创建时间:" );
SendKeys.SendWait ( "{F5}" );          //发送F5按键
SendKeys.SendWait ("{Enter}");       //发送回车键
SendKeys.SendWait ( "^s" );       //发送 Ctrl + s 键
SendKeys.SendWait ( "%{F4}" );      // 发送 Alt + F4 键
MessageBox.Show ("文件已经保存成功!");
}
}

注: SendKeys 发送的按键的接收窗体,必须是当前的活动窗体

二、C# 利用 Windows API 控制 外部的 win32 程序

我们这里,用控制 “计算器”程序,算一个 3 + 2 = 5 的算式来做示例。

API 中我们要用到的函数有 FindWindow, FindWindowEx, SendMessage, SetForegroundWindow

对于API的引用方法,大家去看 API 手册,我这里提供一个VB自带的API查询程序

要使用API,需要引入命名空间

using System.Runtime.InteropServices;

下面的API引用部分的代码,放入 class 内部

[DllImport ( "user32.dll", EntryPoint = "FindWindow", SetLastError = true )]
private static extern IntPtr FindWindow( string lpClassName, string lpWindowName );
[DllImport ( "user32.dll", EntryPoint = "FindWindowEx", SetLastError = true )]
private static extern IntPtr FindWindowEx( IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow );
[DllImport ( "user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto )]
private static extern int SendMessage( IntPtr hwnd, uint wMsg, int wParam, int lParam );
[DllImport ( "user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true )]
private static extern void SetForegroundWindow( IntPtr hwnd );

ys

private void button1_Click( object sender, EventArgs e )
{
const uint BM_CLICK = 0xF5; //鼠标点击的消息,对于各种消息的数值,大家还是得去API手册
IntPtr hwndCalc = FindWindow ( null, "计算器" ); //查找计算器的句柄
if ( hwndCalc != IntPtr.Zero )
{
IntPtr hwndThree = FindWindowEx ( hwndCalc, 0, null, "3" ); //获取按钮3 的句柄
IntPtr hwndPlus = FindWindowEx ( hwndCalc, 0, null, "+" );  //获取按钮 + 的句柄
IntPtr hwndTwo = FindWindowEx ( hwndCalc, 0, null, "2" );  //获取按钮2 的句柄
IntPtr hwndEqual = FindWindowEx ( hwndCalc, 0, null, "=" ); //获取按钮= 的句柄
SetForegroundWindow ( hwndCalc );    //将计算器设为当前活动窗口
System.Threading.Thread.Sleep ( 2000 );   //暂停2秒让你看到效果
SendMessage ( hwndThree, BM_CLICK, 0, 0 );
System.Threading.Thread.Sleep ( 2000 );   //暂停2秒让你看到效果
SendMessage ( hwndPlus, BM_CLICK, 0, 0 );
System.Threading.Thread.Sleep ( 2000 );   //暂停2秒让你看到效果
SendMessage ( hwndTwo, BM_CLICK, 0, 0 );
System.Threading.Thread.Sleep ( 2000 );   //暂停2秒让你看到效果
SendMessage ( hwndEqual, BM_CLICK, 0, 0 );
System.Threading.Thread.Sleep ( 2000 );
MessageBox.Show ("你看到结果了吗?");
}
else
{
MessageBox.Show ("没有启动 [计算器]");
}
}

转载于:https://www.cnblogs.com/chenbg2001/archive/2009/01/11/1373706.html

相关文章:

springMVC swagger2

参考地址&#xff1a;https://www.cnblogs.com/exmyth/p/7183753.html https://blog.csdn.net/programmer_sean/article/details/72236948 1. maven 依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId&…

1061 Dating

笔记&#xff1a; 第一个输出根据的是大写字母 第二个输出根据的是0-9andA-N 第三个输出根据的是大写字母和小写字母 知道范围便方便确定边界 两两比对时&#xff0c;先遍历一个字符串&#xff0c;遇到在范围内的字符&#xff0c;看其和第二个字符串同位置的字符是否相等 …

PA 项目创建任务

---- 创建任务 DECLAREp_project_id NUMBER : 155233;p_task_number VARCHAR2(240) : CXYTEST0001;p_task_name VARCHAR2(240) : 接口测试CXYTEST0001;p_task_description VARCHAR2(240) : TASKCXYTEST0001;p_scheduled_start_date DAT…

SSM登陆拦截器实现

首先在springmvc中配置拦截器 <!-- 配置拦截器 --><mvc:interceptors><mvc:interceptor><!-- 拦截所有mvc控制器 --><mvc:mapping path"/**"/><!-- mvc:exclude-mapping是另外一种拦截&#xff0c;它可以在你后来的测试中对某个页面…

AGG 学习笔记

我了解的&#xff21;&#xff27;&#xff27;的总体结构按照文件大致分为&#xff1a;   &#xff11;&#xff09;基本定义&#xff08;config,basics....)&#xff1b;   &#xff12;&#xff09;基本操作、类型&#xff08;主要供&#xff21;&#xff27;&#xff2…

1073 Scientific Notation

笔记&#xff1a;这是我迄今为止写过的最复杂的字符串处理算法题。 收获&#xff1a;分而治之&#xff0c;想不清楚就自己设计测试用例和结果。列举然后归类。 以下是程序流程图 #include<cstdio> #include<cmath> #include<cstring> #include<algorith…

几个笔试题目总结

1、阿里某个笔试题&#xff0c;两个字符串text&#xff0c;query&#xff0c;找到text中包含的最长的query的字串&#xff1a; public static String subStr(String text, String query) {if (text ! null && query ! null) {int length query.length();for (int i 0…

baidu mp3竟然还加密,太扯了

baidu mp3竟然还加密&#xff0c;太扯了 public class BaiduHelper { static int F 0; static string I "", J ""; static string O ""; static string E ""; static int[] K new int[1000…

Ubuntu 之linux与windows互传文件

Windows系统下与linux传输文件 windows环境下&#xff0c;windows传出数据到linux下 确保ubuntu安装了ssh服务端。如果没有安装&#xff0c;使用以下命令安装&#xff1a; sudo aptget install ssh service sshd restart 2.windows下下载pscp.exe软件从PuTTY官方网站下载pscp.e…

1048 数字加密 --非满分

16/20 非满分&#xff0c;待来日复习双指针再分析原因 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<bits/stdc.h> using namespace std;void reverStr(char str[]){int len strlen(str);for(int i0;i&l…

端到端对话模型新突破!Facebook发布大规模个性化对话数据库

作者&#xff5c;Pierre-Emmanuel Mazare 等译者&#xff5c;郝毅编辑&#xff5c;Debra出处丨 AI 前线AI 前线导读&#xff1a;聊天机器人是目前非常流行的一种人工智能系统。目前大部分聊天机器人的衔接性都不是很好&#xff0c;尤其是在没有主动的重调优策略下训练出的端到端…

上传文件大小的配置Webcong

修改Webcong文件:<system.web><httpRuntime maxRequestLength"40690" useFullyQualifiedRedirectUrl"true" executionTimeout"6000" useFullyQualifiedRedirectUrl"false" minFreeThreads"…

1001 A+B Format

由于逗号的有无是从末尾数起&#xff0c;满足三个数(且高位还有数)就加逗号&#xff0c;所以有必要把字符串反转&#xff0c;然后寻找数组下标和3的关系 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace st…

[转]数据库建立索引的一般依据

建立索引常用的规则如下&#xff1a; 1、表的主键、外键必须有索引&#xff1b; 2、数据量超过300的表应该有索引&#xff1b; 3、经常与其他表进行连接的表&#xff0c;在连接字段上应该建立索引&#xff1b; 4、经常出现在Where子句中的字段&#xff0c;特别是大表的字段&…

为图片添加半透明遮罩效果

平时为图片添加半透明遮罩效果&#xff0c;我的做法如下&#xff1a;利用标签i实现背景半透明遮罩。当鼠标hover时, 提高i的背景色透明度值background-color: rgba(0, 0, 0, .6) <p class"opacity-black-position"><a href"#"><img src&quo…

linux下typora安装

# optional, but recommended sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE# add Typoras repository sudo add-apt-repository deb https://typora.io ./linux/ sudo apt-get update# install typora sudo apt-get install typora

1005 Spell It Right

基本步骤是&#xff1a;100位的数字longlong也存不下&#xff0c;作为字符串读入&#xff0c;对字符串进行遍历&#xff0c;每个字符减去0加到总和sum上&#xff0c;再将整形的总和sum转化为字符串&#xff0c;对得到的字符串进行遍历&#xff0c;将每个字符映射到英文单词上。…

C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

在多线程的程序中&#xff0c;经常会出现两种情况&#xff1a; 一种情况&#xff1a; 应用程序中&#xff0c;线程把大部分的时间花费在等待状态&#xff0c;等待某个事件发生&#xff0c;然后才能给予响应 这一般使用ThreadPool&#xff08;线程池&#xf…

使用Node.js快速搭建WebSocket server

原文地址&#xff1a;http://my.oschina.net/yushulx/blog/309413 目录[-] 安装服务端客户端参考安装 ?1npm install ws服务端 server.js ?12345678var WebSocketServer require(ws).Server, wss new WebSocketServer({port: 8080});wss.on(connection, function(ws) {ws.o…

android采用MVP完整漫画APP、钉钉地图效果、功能完善的音乐播放器、仿QQ动态登录效果、触手app主页等源码...

Android精选源码 一个可以上拉下滑的Ui效果&#xff0c;觉得好看可以学学 APP登陆页面适配 一款采用MVP的的完整漫画APP源码 android实现钉钉地图效果源码 一个使用单个文字生成壁纸图片的app android 仿QQ动态背景登录效果源码 功能完善的Android 手机本地音乐文件播放器 andr…

1035 Password

很适合用结构体数组的一道题 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std;struct info{char usr[11]"";char pwd[11]"";bool changed false; }infos[1010];int main(){int n,…

Android -- DrawerLayout

抽屉效果的导航菜单 喜欢知乎的都应该装的用知乎日报吧~这里指Android的不是IOS的。知乎日报的导航菜单就是用DrawerLayout实现的。 觉得这种侧滑的抽屉效果的菜单很好。 不用切换到另一个页面&#xff0c…

Socketserver 笔记

引入Socketserver的背景&#xff1a;我们之前使用socket编程的时候&#xff0c;Server端创建一个连接循环&#xff08;建立连接&#xff09;一个通信循环&#xff08;基于一次连接建立通信循环&#xff09;&#xff0c;&#xff08;这里的黏包问题我们的实现方式是&#xff1a;…

Delphi 调用C#编写的WebService 参数为Null解决方法

今天测试.net 2.0的WebService&#xff0c;发现了一个大问题。就是无法获取参数&#xff0c;参数永远是null。当然了使用.net调用 没有任何问题&#xff0c;web测试页也正常。不论是Delphi7还是java调用的结果的都是一样的&#xff0c;难道是.net 2.0的Bug&#xff1f; 测试结…

1025 PAT Ranking

1. 考生的编号是数字字符串&#xff0c;但是没必要转化成整数再比较&#xff0c;可以直接用strcmp() 2. 对整体的排名进行编号时所有信息都已经齐备&#xff0c;可以边编号边输出 3. 需要有些思量的地方是部分编号&#xff0c;当当前学生的分数不等于他上一个该怎么办 4. 真…

C#编写的多生产者多消费者同步问题

// 多个生产者和多个消费者&#xff0c;能生产n个产品的情况using System; using System.Threading;public class HoldIntegerSynchronized{private int[] buffer; //缓冲区private int occupiedBufferCount 0;private int readPosition 0 , writePosition 0;//下一个读到的…

展望2009,回眸2008

2008年真正的过去了&#xff0c;已经感觉不到2008年的存在。 2009年来了&#xff0c;似乎真正的来了。 生活的压力更大了&#xff0c;工作也不太顺利。 希望越来越好&#xff0c;也不知道是不是真的该跳槽了。 待在这里很郁闷。 转载于:https://www.cnblogs.com/tacker/archive…

m_Orchestrate learning system---七、如何快速学好前端

m_Orchestrate learning system---七、如何快速学好前端 一、总结 一句话总结&#xff1a;看视频啊&#xff0c;系统看视频啊 1、如何解决单词数字太长超出边界的问题&#xff1f; word-wrap 把编辑删除都挤跑了 2、amaze ui中a标签和button标签可以互换么&#xff1f; 其实弄上…

1062 Talent and Virtue

1.在结构体里面设置total_grades属性是明智之举&#xff0c;但是不可以在结构体内得到total_gradesvirtue_gradetalent_grade; 2.弄清题意&#xff0c;对人进行分类&#xff0c;等级越高type值越小&#xff0c;但是注意分的类别也许出现交叉的情况&#xff0c;细的要出现在粗的…

用百度直达号获取新用户 让顾客直达商家服务

直达号是什么? 直达号&#xff0c;商家在百度移动平台的官方服务账号。基于移动搜索、账号、地图、个性化推荐等多种方式&#xff0c;让顾客随时随地直达商家服务。 直达号其实就是两个功能&#xff1a;  √ 提供一个手机网站模板&#xff0c;入住商家可以建自己的手机网站。…