此方法是類比鍵盤的,所以必須傳入鍵盤資料。
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/
首頁,要說明幾個概念:
- Win32 平台是 訊息驅動模式
- .Net 架構是 事件驅動模式
- 標題所指的 “控制外部程式”,外部程式是指與本程式無內在相關性的另外一個程式
基於上面提到的,對於.NET的winform程式,在預設情況下(即未對接收訊息的事件做自訂處理,說白了:就是沒有 重寫/覆寫(override)表單(Form)的DefWndProc 事件),.Net 的 winform 程式,是不響應所接收到的自訂訊息的。
我們這裡要討論的內容,就分為兩種情況:
- C#/.NET的程式,控制外部的 win32程式(win16不做考慮)
- C#/.NET的程式,控制外部的 .NET程式
從標題,大家也看到, C# 對外部程式的控制, 我們也分為兩種情況來討論:
- .NET 平台內建的 SendKeys 和 Process 結合的方式
- 完全利用 Windows API 的訊息機制 的方式
一、.NET平台內建的 Process 和 SendKeys 結合的方式
本例子,用 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 發送的按鍵的接收表單,必須是當前的活動表單
二、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 );
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 ("沒有啟動 [計算機]"); }
}