在做自動化測試時,有時會忘記把測試機器的輸入法調成英文狀態,這就導致Sendkey()
輸入時是中文,導致測試失敗,所以我們需要在運行測試前確保輸入法是英文狀態,最保險的做法是Win+Space
鍵直接切換到 ENG英語輸入法
,那麼該如何自動實現呢?
一、參考研究
查了大部分資料,主流的提供這兩種方法更改輸入法
InputLanguage
接口,設置InputLanguage.CurrentInputLangaue
屬性,位於System.Window.Form.dll
中,使用時需要引用該dllWin32 API
,模擬鍵盤快捷鍵,Win+Space
鍵切換輸入法
我的測試程序希望更改計算機系統全局輸入法,而第一種方案不能更改系統輸入法只能更改自己程序輸入時的狀態,其他程序的輸入法狀態不能改變。所以只能選擇第二種方案
二、模擬快捷鍵
Win32 API
關於鍵盤操作需要用到以下關鍵函數
//第一個參數:虛擬鍵碼
//第二個參數:硬件掃描碼,一般設置爲0即可;
//第三個參數:函數操作的一個標誌位,按鍵壓着或者釋放
//第四個參數:定義與擊鍵相關的附加的32位值,一般設置爲0即可。
[DllImport("User32.dll", EntryPoint = "keybd_event", SetLastError = true)]
public static extern void KeyBoard_Event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
具體的代碼就不在這裏放了,文章末尾有完整代碼庫。現在切換輸入法的問題解決了,但是怎麼自動設置我們預先想要的輸入法呢?搜了很多資料,不管是牆內還是牆外好像還沒人有這麼奇怪的需求,正好前段時間研究瞭如何判斷兩張圖像的相似度,就想着用計算機視覺方法嘗試解決下
三、圖像處理
1. 設計思路
這裏把我完整的思路先用文字敘述一遍:
- 調用
Win32 API
模擬Win+Space
鍵,按一下切換輸入法,使得輸入法窗口出現 - 獲取右邊輸入法窗口的截圖並保存
- 設置原始輸入法圖片(比如
ENG輸入法
,只對ENG截圖保存) - 使用原始輸入法圖片對第2步中的截圖區域進行模板匹配,找到匹配區域並保存
- 計算原始輸入法圖片和第4步中匹配區域圖片的相似程度(SSIM指數)
- 對每種輸入法均做上述操作
- 求出圖片相似程度最高值對應的切換輸入法次數N
- 再調用N次
Win+Sapce
鍵切換輸入法,最後輸入法就是我們想預設的
2. 圖片說明
這是原始圖片,也就是我們想要的默認輸入法(注意,這是選中狀態下的ENG截圖)
這是Win+Space
鍵切換輸入法時的截圖
這是原始圖像在上述截圖中的匹配區域(注意,這不是我手動加上的,是模板匹配自動生成矩形框),其實這時候我們可以看到三個矩形都找到了ENG 英語美國
這個輸入法,但是它們背景顏色有深淺之分,所以需要對比這三次的結果
爲了對比結果,將上述紅框裏的內容導出成和原始圖像一樣尺寸的圖像,計算導出後的圖像和原始圖像的結構相似度(SSIM),得到最高相似度後顯然我們知道是第二次點擊時得到的,所以最後又重新Win+Sapce
鍵切換,只是這次我們知道只需切換2次就可以匹配上我們默認的輸入法,從而成功的設置想要的輸入法
關於如何比較兩張圖片相似度,參考我的這篇博客 【OpenCvSharp】使用SSIM指數衡量圖片相似度
四、完整代碼
完整代碼已經上傳到Github, 請移步自取 InputLanguage.Editor
2020-04-21 更新
遇到了很奇怪的問題,在測試機器上怎麼也識別不出來EN輸入法,最終發現問題了。因爲選中輸入法時,有一種Hover上去的效果,Hover的顏色與Windows系統主題顏色一致
而測試機器上主題顏色不一致
所以設置好測試機器的主題