此方法是模拟键盘的,所以必须传入键盘数据。
SendKeys.SendWait("{F5}"); //发送F5按键 SendKeys.SendWait("^s"); //发送 Ctrl + s 键 SendKeys.SendWait("%{F4}"); // 发送 Alt + F4 键 /*按键 代码 BACKSPACE {BACKSPACE}, {BS}, 或 {BKSP} BREAK {BREAK} CAPS LOCK {CAPSLOCK} DEL or DELETE {DELETE} 或 {DEL} DOWN ARROW {DOWN} END {END} ENTER {ENTER}或 ~ ESC {ESC} HELP {HELP} HOME {HOME} INS or INSERT {INSERT} 或 {INS} LEFT ARROW {LEFT} NUM LOCK {NUMLOCK} PAGE DOWN {PGDN} PAGE UP {PGUP} PRINT SCREEN {PRTSC} RIGHT ARROW {RIGHT}
SendKeys.SendWait("+{TAB}");
SendKeys.SendWait("%f");//alt+f
SendKeys.SendWait("{Tab}");
SendKeys.SendWait("{Enter}")
多次按键的代码
为了指定重复键,使用 {key number} 的形式。必须在 key 与 number 之间放置一个空格。例如,{LEFT 42} 意指 42 次按下
LEFT ARROW 键;{h 10} 则是指 10 次按下 H 键。
http://www.zu14.cn/2008/10/28/csharp_api_sendkeys/
首页,要说明几个概念:
基于上面提到的,对于.NET的winform程序,在默认情况下(即未对接收消息的事件做自定义处理,说白了:就是没有 重写/覆写(override)窗体(Form)的DefWndProc 事件),.Net 的 winform 程序,是不响应所接收到的自定义消息的。
我们这里要讨论的内容,就分为两种情况:
从标题,大家也看到, C# 对外部程序的控制, 我们也分为两种情况来讨论:
本例子,用 C# 的一个Winform程序,创建一个指定路径的文本文件,写入某些内容后,并保存。
为了看清效果,将 Form 的 TopMost 设为 true
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 发送的按键的接收窗体,必须是当前的活动窗体
我们这里,用控制 “计算器”程序,算一个 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 );
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 ("没有启动 [计算器]");
}
}