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

來源:互聯網
上載者:User

此方法是類比鍵盤的,所以必須傳入鍵盤資料。

 

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 程式,是不響應所接收到的自訂訊息的。

我們這裡要討論的內容,就分為兩種情況:

  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

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 ("沒有啟動 [計算機]");
      }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.