利用C# WINFORM 模拟操作制作外挂

给客户制作了一个刷游戏任务的PC外挂,利用C#获取窗口句柄,进行操作实现。

此方法,只适用于可以获取到句柄的游戏,获取不到的可以用按键精灵制作,手机也一样。

现在年代的外挂基本都基于简化操作,而不是以前的那种攻击数据,现在技术很难突破,除非自己人,实现核心代码如下,记录一下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
namespace LSWZ
{
    /// <summary>
    /// 游戏控制
    /// </summary>
    public class GamePlay
    {
        /// <summary>
        /// 获取窗体句柄
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName"></param>
        /// <returns></returns>
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
        /// <summary>
        /// 获取窗体句柄
        /// </summary>
        /// <param name="hwnd">目标句柄</param>
        /// <param name="nCmdShow">参考相关文档</param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
        /// <summary>
        /// 设置目标窗体大小,位置
        /// </summary>
        /// <param name="hWnd">目标句柄</param>
        /// <param name="x">目标窗体新位置X轴坐标</param>
        /// <param name="y">目标窗体新位置Y轴坐标</param>
        /// <param name="nWidth">目标窗体新宽度</param>
        /// <param name="nHeight">目标窗体新高度</param>
        /// <param name="BRePaint">是否刷新窗体</param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);
        [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", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;//最左坐标
            public int Top;//最上坐标
            public int Right;//最右坐标
            public int Bottom;//最下坐标
        }
        //消息发送API
        [DllImport("user32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(
             IntPtr hWnd,        // 信息发往的窗口的句柄
            int Msg,            // 消息ID
             int wParam,         // 参数1
             int lParam            // 参数2
         );
        IntPtr hWnd;
        GameConfig config;
        Baidu.Aip.Ocr.Ocr client;
        WindowInfo info;
        LoginForm log;
        public void setLog(string s)
        {
            log.SetDtText("窗口【" + info.aWnd + "】:" + DateTime.Now);
            log.SetDtText("窗口【" + info.aWnd + "】:" + s);
        }
        public void start(GameConfig c, WindowInfo i, Baidu.Aip.Ocr.Ocr x, LoginForm cur)
        {
            log = cur;
            info = JsonConvert.DeserializeObject<WindowInfo>(JsonConvert.SerializeObject(i));
            hWnd = info.hWnd;
            config = c;
            client = x;
            string word = GetWinText();
            setLog("已启动");
            // 显示窗口
            ShowWindow(info.aWnd, 4);
            // 设置窗口分辨率 450 * 760
            MoveWindow(info.aWnd, 0, 0, 450, 760, true);
            setLog("设置分辨率完成");
            // 启动任务
            while (true)
            {
                setLog("开始执行任务");
                goHome();
                threadPlay();
                setLog("执行任务完毕");
                Thread.Sleep(60 * 60 * 1000);
            }
        }
        /// <summary>
        /// 出城
        /// </summary>
        public void PlayChuCheng()
        {
            string word = GetWinText();
            SendMsg(44, 695);
            Thread.Sleep(5000);
            if (word.IndexOf("\"回\"") > -1)
            {
                SendMsg(44, 695);
                Thread.Sleep(5000);
            }
            setLog("出城");
        }
        /// <summary>
        /// 回到左上角
        /// </summary>
        public void DingWei()
        {
            setLog("恢复默认坐标");
            //没有固定坐标依靠,创造坐标
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(100, 360, 100, 720);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            SendTuoDongMsg(200, 100, 400, 100);
            setLog("恢复默认坐标完成");
        }
        /// <summary>
        /// 回城
        /// </summary>
        public void PlayHuiCheng()
        {
            string word = GetWinText();
            SendMsg(44, 695);
            Thread.Sleep(5000);
            //回城恢复默认缩放,别影响滑动定位
            if (word.IndexOf("\"出\"") > -1)
            {
                SendMsg(44, 695);
                Thread.Sleep(5000);
            }
            setLog("执行回城");
        }
        /// <summary>
        /// 截取字符串中开始和结束字符串中间的字符串
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="startStr">开始字符串</param>
        /// <param name="endStr">结束字符串</param>
        /// <returns>中间字符串</returns>
        public string SubstringSingle(string source, string startStr, string endStr)
        {
            Regex rg = new Regex("(?<=(" + startStr + "))[.\\s\\S]*?(?=(" + endStr + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            return rg.Match(source).Value;
        }
        public int SubstringSingle(string source)
        {
            string r = @"[0-9]+";
            Regex reg = new Regex(r, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            MatchCollection mc = reg.Matches(source);
            if (mc.Count > 0)
            {
                try
                {
                    return Convert.ToInt32(mc[0].Groups[0].Value);
                }
                catch (Exception)
                {
                    return 0;
                }
            }
            return 0;
        }
        public void goHome()
        {
            setLog("判断是否处于城内");
            string word = GetWinText();
            if (word.IndexOf("\"出\"") > -1 || word.IndexOf("\"回\"") > -1)
            {
                setLog("已处于城内");
                return;
            }
            //关闭
            setLog("关闭");
            SendMsg(26, 48);
            goHome();
        }
        public void goDuiLie()
        {
            setLog("判断是否处于城外");
            string word = GetWinText();
            if (word.IndexOf("队列") > -1)
            {
                setLog("已处于城外");
                return;
            }
            //关闭
            setLog("关闭");
            SendMsg(26, 48);
            goDuiLie();
        }
        public void threadPlay()
        {
            //日常
            RiChangPlay();
            WaPlay();
            //打野
            DaYePlay();
            //采集
            CaiJiPlay();
        }
        /// <summary>
        /// 打野级别调整
        /// </summary>
        public bool DaYeLv()
        {
            setLog("打野,正在降低打野等级");
            //点击查找
            SendMsg(327, 600);
            //获取当前打野级别
            string word = GetWinText(1);
            string w = SubstringSingle(word, "等级", "/");
            int lv = SubstringSingle(w);
            if (lv > config.daye.lv)
            {
                setLog("打野,降低打野等级成功");
                SendMsg(53, 620);
                //关闭
                SendMsg(26, 48);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 获取体力
        /// </summary>
        public int getTiLi()
        {
            setLog("打野,获取当前体力");
            SendMsg(26, 48);
            SendMsg(135, 615);
            string word = GetWinText();
            //退出头像界面
            SendMsg(33, 41);
            SendMsg(33, 41);
            //获取当前体力
            string w = SubstringSingle(word, "当前体力:", "\"");
            return SubstringSingle(w);
        }
        /// <summary>
        /// 打野
        /// </summary>
        public bool DaYe(int tili)
        {
            setLog("执行打野");
            bool isOK = true;
            //有体力就打野
            while (tili > 5)
            {
                //表示不在主界面
                goDuiLie();
                //判断是否有空闲队列
                string kongxian = GetWinText();
                if (kongxian.IndexOf("空") > -1)
                {
                    setLog("打野,有空闲队列");
                    //点击查找
                    SendMsg(327, 600);
                    //搜索
                    SendMsg(200, 700);
                    kongxian = GetWinText();
                    //判定是否找到野怪,如果没找到
                    if (kongxian.IndexOf("目标现在搜索不到") > -1)
                    {
                        setLog("打野,野怪没了");
                        //关闭提示
                        SendMsg(200, 420);
                        //如果调整打野级别失败
                        if (!DaYeLv())
                        {
                            setLog("停止打野,低于打野最低等级");
                            //打野停止
                            isOK = false;
                            break;
                        }
                    }
                    else
                    {
                        setLog("打野中");
                        //点击野怪
                        SendMsg(200, 360);
                        SendMsg(210, 495);
                        //使用编队一
                        SendMsg(78, 85);
                        //出征
                        SendMsg(320, 690);
                        //不管有没有打倒都扣除体力
                        tili = tili - 5;
                        setLog("恭喜你打了一只野,血赚");
                    }
                }
                else
                {
                    setLog("打野,等待空闲队列");
                }
                //等待五秒
                Thread.Sleep(5000);
            }
            return isOK;
        }
        /// <summary>
        /// 撤队
        /// </summary>
        public void CheLiDuiWu()
        {
            setLog("执行撤回队伍操作");
            string kongxian = GetWinText();
            //如果有行军
            if (kongxian.IndexOf("行军") > -1)
            {
                string w = SubstringSingle(kongxian, "行军X", "空");
                int xingjun = SubstringSingle(w);
                if (xingjun == 0)
                {
                    xingjun = 5;
                }
                int[] xingjun_list = { 600, 566, 530, 495, 460 };
                for (int i = 0; i < xingjun; i++)
                {
                    //撤队
                    SendMsg(148, xingjun_list[i]);
                    SendMsg(243, 420);
                    SendMsg(372, 257);
                }
            }
        }
        public void CaiJiPlay()
        {
            if (config.caiji.enable)
            {
                setLog("执行采集任务");
                //出城
                PlayChuCheng();
                goDuiLie();
                //判断空闲队伍数量
                string kongxian = GetWinText();
                //如果有行军
                int kx = 5;
                if (kongxian.IndexOf("行军") > -1)
                {
                    string w = SubstringSingle(kongxian, "行军X", "空");
                    kx = kx - SubstringSingle(w);
                }
                //点击查找
                SendMsg(327, 600);
                //推动回到最后
                SendTuoDongMsg(359, 528, 230, 528);
                //关闭面板
                SendMsg(26, 48);
                setLog("采集,初始化");
                List<int> caiji_list = new List<int>();
                //{ 180, 246, 310, 370 }
                //如果选择了粮食
                if (config.caiji.type_ls)
                {
                    caiji_list.Add(180);
                }
                if (config.caiji.type_mt)
                {
                    caiji_list.Add(246);
                }
                if (config.caiji.type_tk)
                {
                    caiji_list.Add(310);
                }
                if (config.caiji.type_bs)
                {
                    caiji_list.Add(370);
                }
                if (caiji_list.Count == 0)
                {
                    caiji_list.Add(180);
                    caiji_list.Add(246);
                    caiji_list.Add(310);
                    caiji_list.Add(370);
                }
                for (int i = 0; i < kx; i++)
                {
                    setLog("采集,执行中");
                    //点击查找
                    SendMsg(327, 600);
                    Random rd = new Random();
                    int chooes = rd.Next(caiji_list.Count);
                    SendMsg(caiji_list[chooes], 530);
                    SendMsg(200, 700);
                    SendMsg(200, 360);
                    SendMsg(296, 360);
                    SendMsg(320, 690);
                    setLog("采集,执行完毕");
                }
            }
        }
        /// <summary>
        /// 打野控制
        /// </summary>
        public void DaYePlay()
        {
            //如果可以打野
            if (config.daye.enable)
            {
                setLog("执行打野任务");
                //出城
                PlayChuCheng();
                setLog("打野,初始化");
                //初始化
                //点击查找
                SendMsg(327, 600);
                //推动回到第一
                SendTuoDongMsg(30, 528, 200, 528);
                //点击打野
                SendMsg(30, 528);
                //调整打野等级
                SendMsg(255, 620);
                SendMsg(255, 620);
                SendMsg(255, 620);
                SendMsg(255, 620);
                SendMsg(255, 620);
                SendMsg(255, 620);
                SendMsg(255, 620);
                //关闭面板
                SendMsg(26, 48);
                //获取体力
                int tili = getTiLi();
                //执行打野,默认大于等于100点体力就干活
                setLog("打野,判断体力是否过多");
                bool isdd = false;
                if (tili >= 100)
                {
                    isdd = true;
                    setLog("打野,体力过多");
                    //撤离队伍
                    CheLiDuiWu();
                    //打野
                    DaYe(tili);
                }
                //当前设定是否使用体力
                setLog("打野,判断是否可以使用体力");
                if (config.daye.tili)
                {
                    int tiliNew = 0;
                    //撤离队伍
                    if (config.daye.tili_num > 0)
                    {
                        isdd = true;
                        setLog("打野,根据体力上限执行打野");
                        CheLiDuiWu();
                    }
                    //达到体力上限
                    while (config.daye.tili_num > 0)
                    {
                        //使用体力
                        shiyongTili();
                        //获取当前体力
                        tiliNew = getTiLi();
                        //扣除上限
                        config.daye.tili_num = config.daye.tili_num - (tiliNew - tili);
                        //标记当前体力
                        tili = tiliNew;
                        //执行打野
                        if (!DaYe(tili))
                        {
                            //表示目前打野等级不满足最低要求
                            break;
                        }
                        //打野完成,矫正体力
                        tili = getTiLi();
                    }
                }
                if (isdd)
                {
                    //休息五分钟等待队伍回来
                    Thread.Sleep(5 * 60 * 1000);
                }
            }
        }
        /// <summary>
        /// 使用体力
        /// </summary>
        public void shiyongTili()
        {
            setLog("正在使用体力");
            //打开体力界面
            SendMsg(26, 48);
            SendMsg(135, 615);
            //使用体力
            SendMsg(343, 237);
            SendMsg(200, 460);
            //退出头像界面
            SendMsg(33, 41);
            SendMsg(33, 41);
            setLog("使用体力完成");
        }
        /// <summary>
        /// 联盟挖
        /// </summary>
        public void WaPlay()
        {
            // 执行日常
            if (config.richang.enable)
            {
                ////////////////////////////联盟宝藏///////////////////////////////////
                if (config.richang.bcNum > 0)
                {
                    setLog("执行联盟宝藏任务");
                    //打开联盟
                    SendMsg(315, 695);
                    //打开宝藏
                    SendMsg(203, 465);
                    setLog("正在挖联盟宝藏");
                    //刷新执行两次
                    SendMsg(196, 680);
                    SendMsg(196, 680);
                    //给老子挖
                    SendMsg(330, 290);
                    setLog("恭喜你,挖了一个宝藏,天美血亏");
                    //切换
                    SendMsg(206, 87);
                    SendMsg(206, 87);
                    SendMsg(325, 290);
                    SendMsg(325, 290);
                    setLog("联盟宝藏请求盟友");
                    //切换
                    SendMsg(311, 87);
                    SendMsg(327, 292);
                    SendMsg(327, 292);
                    SendMsg(202, 185);
                    setLog("联盟宝藏帮助盟友");
                    // 退出界面
                    SendMsg(377, 42);
                    setLog("退出联盟宝藏");
                }
                ////////////////////////////联盟宝藏 - end/////////////////////////////
            }
        }
        /// <summary>
        /// 进入神将台
        /// </summary>
        public bool goShenJiang()
        {
            DingWei();
            setLog("正在进入神将台界面");
            SendTuoDongMsg(200, 360, 0, 360);
            SendTuoDongMsg(200, 360, 0, 360);
            SendTuoDongMsg(200, 360, 0, 360);
            SendTuoDongMsg(200, 360, 0, 360);
            SendTuoDongMsg(200, 360, 200, 0);
            SendTuoDongMsg(200, 360, 200, 300);
            SendMsg(270, 370);
            SendMsg(248, 452);
            string word = GetWinText();
            // 进入神将台
            if (word.IndexOf("点将") > -1)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 进入神将台
        /// </summary>
        public bool goXunLong()
        {
            DingWei();
            setLog("正在进入寻龙界面");
            SendTuoDongMsg(200, 360, 0, 360);
            SendTuoDongMsg(200, 360, 0, 360);
            SendMsg(294, 434);
            SendMsg(215, 557);
            string word = GetWinText();
            // 进入神将台
            if (word.IndexOf("连抽必得紫色龙魂") > -1)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 日常控制
        /// </summary>
        public void RiChangPlay()
        {
            // 执行日常
            if (config.richang.enable)
            {
                setLog("执行常规任务");
                PlayHuiCheng();
                ////////////////////////////执行寻龙////////////////////////////
                if (config.richang.xunlongNum > 0 || config.richang.xunlongGaoJiNum > 0)
                {
                    bool isOK = goXunLong();
                    //第二次调用
                    if (!isOK)
                    {
                        setLog("重新进入寻龙界面");
                        isOK = goXunLong();
                    }
                    // 进入神将台
                    if (isOK)
                    {
                        string word = GetWinText(1);
                        setLog("已进入寻龙界面");
                        // 执行日常免费寻龙
                        if (word.IndexOf("今日剩余免费次数") > -1 && word.IndexOf("今日剩余免费次数:0/3") == -1)
                        {
                            setLog("正在执行寻龙每日免费抽取任务");
                            //寻龙
                            SendMsg(110, 631);
                            //确定
                            SendMsg(303, 575);
                        }
                        setLog("检查是否指定寻龙");
                        // 执行指定寻龙
                        while (config.richang.xunlongGaoJiNum > 0)
                        {
                            //10连抽 寻龙
                            SendMsg(303, 633);
                            // 等待10连抽动画
                            Thread.Sleep(5000);
                            //确定
                            SendMsg(303, 575);
                            config.richang.xunlongGaoJiNum--;
                        }
                        setLog("指定寻龙执行完毕");
                        // 退出寻龙界面
                        SendMsg(33, 41);
                        setLog("退出寻龙");
                    }
                }
                ////////////////////////////执行寻龙 - end////////////////////////////
                ////////////////////////////执行神将台////////////////////////////////
                if (config.richang.shenjiangNum > 0 || config.richang.shenjiangGaoJiNum > 0 || config.richang.jinengGaoJiNum > 0 || config.richang.jiceGaoJiNum > 0)
                {
                    bool isOK = goShenJiang();
                    //第二次调用
                    if (!isOK)
                    {
                        setLog("重新进入神将台界面");
                        isOK = goShenJiang();
                    }
                    // 进入神将台
                    if (isOK)
                    {
                        string word = GetWinText(1);
                        setLog("已进入神将台界面");
                        // 执行日常免费寻龙
                        if (word.IndexOf("今日剩余免费次数") > -1 && word.IndexOf("今日剩余免费次数:0/5") == -1)
                        {
                            setLog("正在执行武将每日免费抽取任务");
                            //武将
                            SendMsg(98, 357);
                            //中间确定
                            SendMsg(204, 577);
                            //确定
                            SendMsg(303, 575);
                        }
                        //切换
                        SendMsg(249, 93);
                        word = GetWinText(1);
                        if (word.IndexOf("今日剩余免费次数") > -1 && word.IndexOf("今日剩余免费次数:0/5") == -1)
                        {
                            setLog("正在执行技能每日免费抽取任务");
                            //技能
                            SendMsg(100, 576);
                            //中间确定
                            SendMsg(204, 577);
                            //确定
                            SendMsg(303, 575);
                        }
                        //切换
                        SendMsg(345, 95);
                        word = GetWinText(1);
                        if (word.IndexOf("今日剩余免费次数") > -1 && word.IndexOf("今日剩余免费次数:0/5") == -1)
                        {
                            setLog("正在执行计策每日免费抽取任务");
                            //计策
                            SendMsg(100, 576);
                            //中间确定
                            SendMsg(204, 577);
                            //确定
                            SendMsg(303, 575);
                        }
                        setLog("检查指定高级招募抽取任务");
                        if (config.richang.shenjiangGaoJiNum > 0)
                        {
                            //切换
                            SendMsg(158, 95);
                            // 执行指定高招
                            while (config.richang.shenjiangGaoJiNum > 0)
                            {
                                //10连抽 高招
                                SendMsg(303, 645);
                                // 等待10连抽动画
                                Thread.Sleep(5000);
                                //中间确定
                                SendMsg(204, 577);
                                //确定
                                SendMsg(303, 575);
                                config.richang.shenjiangGaoJiNum--;
                            }
                        }
                        setLog("检查指定技能抽取任务");
                        if (config.richang.jinengGaoJiNum > 0)
                        {
                            //切换
                            SendMsg(249, 93);
                            // 执行指定技能
                            while (config.richang.jinengGaoJiNum > 0)
                            {
                                //10连抽 技能
                                SendMsg(307, 580);
                                // 等待10连抽动画
                                Thread.Sleep(5000);
                                //确定
                                SendMsg(303, 575);
                                config.richang.jinengGaoJiNum--;
                            }
                        }
                        setLog("检查指定计策抽取任务");
                        if (config.richang.jiceGaoJiNum > 0)
                        {
                            //切换
                            SendMsg(345, 95);
                            // 执行指定计策
                            while (config.richang.jiceGaoJiNum > 0)
                            {
                                //10连抽 计策
                                SendMsg(308, 590);
                                // 等待10连抽动画
                                Thread.Sleep(5000);
                                //确定
                                SendMsg(303, 575);
                                config.richang.jiceGaoJiNum--;
                            }
                        }
                        setLog("完成神将台指定抽取任务");
                        // 退出界面
                        SendMsg(33, 41);
                        setLog("退出神将台");
                    }
                    else
                    {
                        setLog("进入神将台失败");
                    }
                }
                ////////////////////////////执行神将台 - end///////////////////////////
            }
        }
        /// <summary>
        /// 获取OCR识别后内容
        /// </summary>
        public string GetWinText(int type = 0)
        {
            setLog("OCR识别");
            var image = GetWindowCapture();
            Newtonsoft.Json.Linq.JObject result;
            if (type == 1)
            {
                result = client.AccurateBasic(image);
            }
            else
            {
                result = client.GeneralBasic(image);
            }
            setLog("OCR识别完成");
            return result.ToString();
        }
        [DllImport("user32.dll")]
        public static extern bool PrintWindow(
             IntPtr hwnd,                // Window to copy,Handle to the window that will be copied.
             IntPtr hdcBlt,              // HDC to print into,Handle to the device context.
             UInt32 nFlags               // Optional flags,Specifies the drawing options. It can be one of the following values.
        );
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(
         IntPtr hwnd
        );
        /// <summary>
        /// 截图返回byte[]
        /// </summary>
        public byte[] GetWindowCapture()
        {
            //RECT windowRect = new RECT();
            //GetWindowRect(info.aWnd, ref windowRect);
            //int width = windowRect.Right - windowRect.Left;
            //int height = windowRect.Bottom - windowRect.Top;
            Bitmap image = new Bitmap(450, 760);
            Graphics gp = Graphics.FromImage(image);
            IntPtr dc = gp.GetHdc();
            PrintWindow(info.aWnd, dc, 0);
            gp.ReleaseHdc();
            gp.Dispose();
            string path = "F:\\LSWZ\\LSWZ\\bin\\Debug\\test.jpg";
            image.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
            return Bitmap2Byte(image);
        }
        /// <summary>
        /// 转义
        /// </summary>
        public byte[] Bitmap2Byte(Bitmap bitmap)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Jpeg);
                byte[] data = new byte[stream.Length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, Convert.ToInt32(stream.Length));
                return data;
            }
        }
        /// <summary>
        /// 发送点击事件
        /// </summary>
        public void SendMsg(int x, int y, int time = 3000)
        {
            PostMessage(hWnd, 0x0201, 1, (y * 65536 + x));
            PostMessage(hWnd, 0x0202, 0, (y * 65536 + x));
            //SendMessage(hWnd, 0x0201, (IntPtr)1, (IntPtr)(y * 65536 + x));
            //Thread.Sleep(300);
            //SendMessage(hWnd, 0x0202, (IntPtr)0, (IntPtr)(y * 65536 + x));
            // 为防止电脑卡,每次点完等待5秒
            setLog("点击事件");
            Thread.Sleep(time);
        }
        /// <summary>
        /// 发送拖动事件
        /// </summary>
        public void SendTuoDongMsg(int x, int y, int x2, int y2)
        {
            PostMessage(hWnd, 0x0201, 1, (y * 65536 + x));
            PostMessage(hWnd, 0x0200, 1, (y2 * 65536 + x2));
            PostMessage(hWnd, 0x0202, 0, (y2 * 65536 + x2));
            setLog("拖动事件");
            Thread.Sleep(1000);
        }
    }
}