非淡泊无以明志,非宁静无以致远 -心静如止水,动于静

AutoKey思想的應用(一)

進行某e化專案的過程中,用戶使用的一個設備是由第三方提供的,但為了實現自動操作第三方提供的軟件程序,想了几個方案:

1. 使用屏幕錄制,然后重放來實現自動操作,雖然在技朮上實現沒有問題,但效果不佳,主要是需要在最終用戶使用前要錄制,而且一旦軟件程序被移動位置,整個就失效了,所以不可靠(not stateble)

2. 第二種方案,用VC Spy++來找到窗口,然后模擬消息事件發送到指定的控件中。用Notepad.exe可以成功,但到了正式環境卻不行,原因是第三方開發的軟件程序使用的不是標准windows控件,而是自己組合的,消息也是自定議的(_USERMSG+),所以要用Spy++仔細查找方可。這種方法比較笨拙不說,而且不易作成一個通過的模塊

3. 模擬Keyboard消息,向當前活動窗口發送快捷鍵。這個方法比較正規,所以下面展示重要代碼 

    public class AutoKey
    {

        public void SendKeyWithAlt(string keys)
        {
  
            //Press Alt Key
            structInput.ki.wVk = (ushort)VK.MENU;
            intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));

            for (int i = 0; i < c_array.Length; i++)
            {
                structInput.ki.wVk = (ushort)c_array[i];
                structInput.ki.wScan = (ushort)MapVirtualKey(c_array[i], 0);
                structInput.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_UNICODE;
                intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
                Thread.Sleep(50);
            }

            //Keyup Alt
            structInput.ki.dwFlags = KEYEVENTF_KEYUP;
            structInput.ki.wVk = (ushort)VK.MENU;
            intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));

        }

        public void SendKeys(string keys)
        {
            char[] c_array;

            for (int i = 0; i < c_array.Length; i++)
            {
                structInput.ki.wVk = (ushort)c_array[i];
                structInput.ki.wScan = (ushort)MapVirtualKey(c_array[i], 0);
                structInput.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_UNICODE ;
                intReturn = SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
                Thread.Sleep(50);
            }
        }

    }
}

 調用代碼如下:

        private void button1_Click(object sender, EventArgs e)
        {
            AutoKey abc = new AutoKey();

            abc.ActiveWindow("notepad");
            abc.SendKeyWithAlt("F");
            Thread.Sleep(50);
            abc.SendKeys("A");

            IntPtr p1 = AutoKey.FindWindow("Notepad", "Untitled - Notepad");
            if (p1 == IntPtr.Zero)
            {
                return;
            }
            IntPtr p2 = AutoKey.FindWindow("#32770", "Save As");
            IntPtr p3 = AutoKey.GetParent(p2);
            int i = 10;
            while (p3 != p1 && i++ < 100)
            {
                Thread.Sleep(10);
                p3 = AutoKey.GetParent(p2);
            }

            abc.SendKeys("MMM");
            Thread.Sleep(50);
            abc.SendKeyWithAlt("S");
        }

posted @ 2008-12-30 19:40  烟雨客  阅读(414)  评论(0编辑  收藏  举报