zoukankan      html  css  js  c++  java
  • 重拾Csharp操控IE浏览器(二)功夫还在IE外

    上篇文章https://www.cnblogs.com/pu369/p/12343259.html主要是对SHDocVw.InternetExplorer的控制,然而有时还需一些win32API才能真正实际完全自动化操作(必要时用spy++查看窗体层次)。

    一些DllImport(在 public partial class Form1 : Form中):

     [DllImport("user32.dll")]
            private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
            private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
            //寻找目标进程窗口
            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
            //设置进程窗口到最前       
            [DllImport("USER32.DLL")]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
            //模拟键盘事件         
            [DllImport("USER32.DLL")]
            public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
            public delegate bool CallBack(IntPtr hwnd, int lParam);
            [DllImport("USER32.DLL")]
            public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
            public delegate bool EnumChildWindow(IntPtr WindowHandle, string num);
            //给CheckBox发送信息
            [DllImport("USER32.DLL", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern int SendMessage(IntPtr hwnd, UInt32 wMsg, int wParam, int lParam);
            //给Text发送信息
            [DllImport("USER32.DLL", EntryPoint = "SendMessage")]
            private static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, string lParam);
            [DllImport("USER32.DLL")]
            public static extern IntPtr GetWindow(IntPtr hWnd, int wCmd);
    
            [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
    
            [DllImport("user32.dll")]
            private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
    
            [DllImport("user32.dll")]
            private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
    
    
           //函数原型;DWORD GetWindowThreadProcessld(HWND hwnd,LPDWORD lpdwProcessld);
            //参数:
            //hWnd:窗口句柄。
            //lpdwProcessld:接收进程标识的32位值的地址。如果这个参数不为NULL,GetWindwThreadProcessld将进程标识拷贝到这个32位值中,否则不拷贝。
            //返回值:返回值为创建窗口的线程标识。
            //C#中使用该函数首先导入命名空间:using System.Runtime.InteropServices;然后写API引用部分的代码,放入 class 内部
             [DllImport("User32.dll", CharSet = CharSet.Auto)]
              public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
           

    1、寻找系统的全部窗体

     static WindowInfo[] GetAllDesktopWindows()
            {
                List<WindowInfo> wndList = new List<WindowInfo>();
                EnumWindows(delegate(IntPtr hWnd, int lParam)
                {
                    WindowInfo wnd = new WindowInfo();
                    StringBuilder sb = new StringBuilder(256);
                    //get hwnd
                    wnd.hWnd = hWnd;
                    //get window name
                    GetWindowTextW(hWnd, sb, sb.Capacity);
                    wnd.szWindowName = sb.ToString();
                    //get window class
                    GetClassNameW(hWnd, sb, sb.Capacity);
                    wnd.szClassName = sb.ToString();
                    Console.WriteLine("Window handle=" + wnd.hWnd.ToString().PadRight(20) + " szClassName=" + wnd.szClassName.PadRight(20) + " szWindowName=" + wnd.szWindowName);
                    //add it into list
                    wndList.Add(wnd);
                    return true;
                }, 0);
                return wndList.ToArray();
            }
    //保存窗体信息的struct
        public struct WindowInfo
        {
            public IntPtr hWnd;
            public string szWindowName;
            public string szClassName;
        }

    用上面的代码,实现获取所有窗体信息

            private void testToolStripMenuItem_Click_2(object sender, EventArgs e)
            {
                var all = GetAllDesktopWindows();
                string s="" ;
                foreach(var b in all)
                {
                    s = s +b.hWnd.ToString() + " ||| " +  b.szClassName +" ||| " +b.szWindowName +"
    ";
                }
                using (StreamWriter sw = new StreamWriter(@"temp.txt", true)) { sw.WriteLine(s); }
                MessageBox.Show("所有窗体信息保存到当前目录temp.txt ");
            }

    用上面的代码,实现根据部分标题找窗体

     private void 根据部分标题找窗口ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                MessageBox.Show("请设置断点查看");
                //枚举窗口,并显示名称和hWnd
                List<string> result = new List<string>();
                WindowInfo[] a = GetAllDesktopWindows();
                int i = 0;
                string s = this.textBox1.Text.Trim();
               
                for (i = 0; i < a.Length; i++)
                {
                    if (a[i].szWindowName.Contains(s))
                    {
                        string msg = "hwnd:" + a[i].hWnd + "  窗口类:" + a[i].szClassName + "  标题:" + a[i].szWindowName;
                       // MessageBox.Show(msg);
                        result.Add(msg);
                    }    
                }
                //请在下一行设置断点           
             }

    2、打开另一个窗体Form

         private void button1_Click(object sender, EventArgs e)
            {            
                Form2 f2 = new Form2();
                f2.Show();
            }

    3、枚举电脑上所有进程

            private void processToolStripMenuItem_Click_1(object sender, EventArgs e)
            {
                MessageBox.Show("请设置断点查看");
                //枚举进程名和_Handle
                string s = "";
                Process[] app = Process.GetProcesses();
                List<string> li = new List<string>();
                foreach (Process p in app)
                {
                    try
                    {
                        s = "进程名:" + p.ProcessName + "  ______________ 进程句柄_Handle:" + p.Handle;
                        li.Add(s);
                    }
                    catch (Exception e1) { e.ToString(); }
    
                }
                var aproess = li;
                //请在下一行设置断点     
            }

    4、用FindWindow根据主窗口标题查找窗体hwnd,再用GetWindowThreadProcessId根据hwnd找进程ID,再用Process.GetProcessById(进程ID).MainWindowTitle得到主窗口标题

     private void poocessIDToolStripMenuItem1_Click(object sender, EventArgs e)
            { 
                //获取计算器窗口句柄 ,需要先打开计算器  
                IntPtr hwnd = FindWindow(null, "计算器");
                if (hwnd != IntPtr.Zero)
                {
                    int calcID;
                    //获取进程ID   
                    GetWindowThreadProcessId(hwnd, out calcID);
                    MessageBox.Show("FindWindow找出计算器hwnd,再GetWindowThreadProcessId得到进程ID:" + calcID.ToString());
                    string t = Process.GetProcessById(calcID).MainWindowTitle;
                    MessageBox.Show("GetProcessById得到计算器MainWindowTitle:" + t);
    
                }
                else
                {
                    MessageBox.Show("没有找到计算器窗口");
                }
            }

    5、控制计算器做加法

            private void testToolStripMenuItem_Click_2(object sender, EventArgs e)
            {
                //根据输入框内容,找有窗口标题符合的窗口
                string title = "计算器";           
                //获取窗口句柄   
                IntPtr hwnd = FindWindow(null, title);
                if (hwnd != IntPtr.Zero)
                {
                    SetForegroundWindow(hwnd);               
                    System.Windows.Forms.SendKeys.SendWait("12");
                    System.Threading.Thread.Sleep(1000);
                    System.Windows.Forms.SendKeys.SendWait("{ADD}");
                    System.Threading.Thread.Sleep(1000);
                    System.Windows.Forms.SendKeys.SendWait("23");               
                    System.Threading.Thread.Sleep(1000);
                    //System.Windows.Forms.SendKeys.SendWait("{TAB}");
                    System.Windows.Forms.SendKeys.SendWait("{ENTER}");
                }
                else
                {
                    MessageBox.Show("没有找到"+title+"窗口");
                }
            }

    6、点击 windows 安全 窗口上的 确定 按钮

            private void testToolStripMenuItem_Click_2(object sender, EventArgs e)
            {
                //查找Windows 安全,点确定确认证书
                IntPtr hwnd = FindWindow(null, "Windows 安全");
                IntPtr childHwnd = FindWindowEx(hwnd, IntPtr.Zero, "DirectUIHWND", null);
                IntPtr childHwnd3_1 = FindWindowEx(childHwnd, IntPtr.Zero, "CtrlNotifySink", null);
                IntPtr childHwnd3_2 = FindWindowEx(childHwnd, childHwnd3_1, "CtrlNotifySink", null);
                IntPtr childHwnd3_3 = FindWindowEx(childHwnd, childHwnd3_2, "CtrlNotifySink", null);
                IntPtr childHwnd3_3_ok = FindWindowEx(childHwnd3_3, IntPtr.Zero, null, null);
                //uint WM_SETTEXT = 0xC;
                //SendMessage(editor, WM_SETTEXT, IntPtr.Zero, "username");
                uint BM_CLICK = 0x00F5;
                SendMessage(childHwnd3_3_ok, BM_CLICK, 0, 0);     //发送点击按钮的消息   
            }

    7、批量生成目录

           private void 生成目录名ToolStripMenuItem1_Click(object sender, EventArgs e)
            {
                List<string> lis = new List<string>() { "目录1", "目录2", "目录3" };
                foreach (string li in lis)
                {
                    if (!Directory.Exists(@"Y:" + li))
                    {
                        Directory.CreateDirectory(@"Y:" + li);
                    }
                }
            }

    8、窗口前置

    SetForegroundWindow(hwnd);  

    9、发邮件

     private void 发邮件ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                //实例化一个发送邮件类。
                MailMessage mailMessage = new MailMessage();
                //发件人邮箱地址,方法重载不同,可以根据需求自行选择。
                mailMessage.From = new MailAddress("XXX@qq.com");
                //收件人邮箱地址。
                mailMessage.To.Add(new MailAddress("XXX@qq.com"));
                //邮件标题。
                mailMessage.Subject = "发送邮件测试-发给自己";
                //邮件内容。
                mailMessage.Body = "这是我给我自己发送的第一份邮件哦!";
    
                //实例化一个SmtpClient类。
                SmtpClient client = new SmtpClient();
                //在这里我使用的是qq邮箱,所以是smtp.qq.com,如果你使用的是126邮箱,那么就是smtp.126.com。
                client.Host = "smtp.qq.com";
                //使用安全加密连接。
                client.EnableSsl = true;
                //不和请求一块发送。           
                client.UseDefaultCredentials = false;
                //验证发件人身份(发件人的邮箱,邮箱里的生成授权码);
                client.Credentials = new NetworkCredential("XX@qq.com", "apueXXXd");
                //发送
                client.Send(mailMessage);
                MessageBox.Show("发送成功");
            }

    10、鼠标模拟点击

            private void testToolStripMenuItem_Click_2(object sender, EventArgs e)
            {
                MouseMove m = new MouseMove();
                m.MouseMoveAndClick(1436, 357);
            }
        class MouseMove
        {
            #region MouseEvent
            [System.Runtime.InteropServices.DllImport("user32")]
            private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
            //移动鼠标 
            const int MOUSEEVENTF_MOVE = 0x0001;
            //模拟鼠标左键按下 
            const int MOUSEEVENTF_LEFTDOWN = 0x0002;
            //模拟鼠标左键抬起 
            const int MOUSEEVENTF_LEFTUP = 0x0004;
            //模拟鼠标右键按下 
            const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
            //模拟鼠标右键抬起 
            const int MOUSEEVENTF_RIGHTUP = 0x0010;
            //模拟鼠标中键按下 
            const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
            //模拟鼠标中键抬起 
            const int MOUSEEVENTF_MIDDLEUP = 0x0040;
            //标示是否采用绝对坐标 
            const int MOUSEEVENTF_ABSOLUTE = 0x8000;
            #endregion
            //这个区域包括任务栏,就是屏幕显示的物理范围
            struct ScreenWH
            {
                //非静态变量不能直接赋值
                public static int x = Screen.PrimaryScreen.Bounds.Width;  //屏幕宽度 
                public static int y = Screen.PrimaryScreen.Bounds.Height;  //屏幕宽度 
            }       
            //x,y是鼠标在屏幕的位置,屏幕左上角为0,0点
            public void MouseMoveAndClick(int _x, int _y)
            {
                mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, _x * 65535 / ScreenWH.x, _y * 65535 / ScreenWH.y, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            }
        }

    11、模拟键盘CTRL+V粘贴操作

           private void textBox1_DoubleClick(object sender, EventArgs e)
            {
                Clipboard.SetDataObject("HELLO WORLD!!!", true);
                KeyBordClick k = new KeyBordClick();
                k.KeyBordPaste();
    
            }
        class KeyBordClick
        {
            [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
            private static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
            const int KEYEVENTF_KEYUP = 0x02;
            const int KEYEVENTF_KEYDOWN = 0x00;
    
            //相当于按下ctrl+v,然后回车
            public void KeyBordPaste()
            {
                keybd_event(Keys.ControlKey, 0, KEYEVENTF_KEYDOWN, 0);
                keybd_event(Keys.V, 0, 0, 0);
                keybd_event(Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0);
                keybd_event(Keys.Enter, 0, 0, 0);
            }
        }

    12、屏幕截图,并设为当前form的背景

          private void testToolStripMenuItem_Click_2(object sender, EventArgs e)
            {
                this.BackgroundImage = CaptureScreen.CaptureScreenA();
            }
        class CaptureScreen
        {
            /// <summary>
            /// 截屏幕成为图像返回
            /// </summary>
            /// <returns></returns>
            public static Image CaptureScreenA()
            {
                //屏幕宽
                int iWidth = Screen.PrimaryScreen.Bounds.Width;
                //屏幕高
                int iHeight = Screen.PrimaryScreen.Bounds.Height;
                //按照屏幕宽高创建位图
                Image img = new Bitmap(iWidth, iHeight);
                //从一个继承自Image类的对象中创建Graphics对象
                Graphics gc = Graphics.FromImage(img);
                //抓屏并拷贝到myimage里
                gc.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(iWidth, iHeight));
                  //保存位图
                //img.Save(@"E:" + Guid.NewGuid().ToString() + ".jpg");
                return img;          
            }
           
        }

    13、图片剪裁类

        public class ImageManager
        {
            /// <summary>
            /// 图像切割
            /// </summary>
            /// <param name="url">图像文件名称</param>
            /// <param name="width">切割后图像宽度</param>
            /// <param name="height">切割后图像高度</param>
            /// <param name="savePath">切割后图像文件保存路径</param>
            /// <param name="fileExt">切割后图像文件扩展名</param>
            public static void Cut(string url, int width, int height, string savePath, string fileExt, string logofile)
            {
                Bitmap bitmap = new Bitmap(url);
                Decimal MaxRow = Math.Ceiling((Decimal)bitmap.Height / height);
                Decimal MaxColumn = Math.Ceiling((decimal)bitmap.Width / width);
                for (decimal i = 0; i < MaxRow; i++)
                {
                    for (decimal j = 0; j < MaxColumn; j++)
                    {
                        string filename = i.ToString() + "," + j.ToString() + "." + fileExt;
                        Bitmap bmp = new Bitmap(width, height);
                        for (int offsetX = 0; offsetX < width; offsetX++)
                        {
                            for (int offsetY = 0; offsetY < height; offsetY++)
                            {
                                if (((j * width + offsetX) < bitmap.Width) && ((i * height + offsetY) < bitmap.Height))
                                {
                                    bmp.SetPixel(offsetX, offsetY, bitmap.GetPixel((int)(j * width + offsetX), (int)(i * height + offsetY)));
                                }
                            }
                        }
                        Graphics g = Graphics.FromImage(bmp);
                        g.DrawString("脚本之家", new Font("黑体", 20), new SolidBrush(Color.FromArgb(70, Color.WhiteSmoke)), 60, height / 2);//加水印
                        ImageFormat format = ImageFormat.Png;
                        switch (fileExt.ToLower())
                        {
                            case "png":
                                format = ImageFormat.Png;
                                break;
                            case "bmp":
                                format = ImageFormat.Bmp;
                                break;
                            case "gif":
                                format = ImageFormat.Gif;
                                break;
                        }
                        bmp.Save(savePath + "//" + filename, format);
                    }
                }
            }
        }
  • 相关阅读:
    Spring Session Logout
    VC6.0 error LNK2001: unresolved external symbol _main解决办法
    JDBC数据库编程基本流程
    JDBC连接SQL Server2008
    JDK的下载、安装及环境变量的配置
    奇数阶幻方口诀
    ping: sendto: Network is unreachable
    new/delete和malloc/free的区别
    MFC的消息管理
    VC++之自定义消息
  • 原文地址:https://www.cnblogs.com/pu369/p/12346370.html
Copyright © 2011-2022 走看看