zoukankan      html  css  js  c++  java
  • 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");
            }

  • 相关阅读:
    ef unitofwork 主从表更新
    自己写的enum转换的一个扩展,
    最近在做政务项目,此种项目,本来并不大,主要原因呢,就是要理好业务需要。
    sql server创建外键,子母表,级联删除。
    js querySelector与getElementById
    写一个system.data.entity的simpledatarepo,实现crudq这些功能,不需要引入entityframework,直接可以使用,用到objectset
    无法更新 EntitySet“W_ReceiveData”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。
    Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31
    开放下载 | 《Knative 云原生应用开发指南》开启云原生时代 Serverless 之门
    有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务
  • 原文地址:https://www.cnblogs.com/sdikerdong/p/1365528.html
Copyright © 2011-2022 走看看