[C#] Winform 抓取所有開啟的Internet Explorer 開啟的網頁,並且抓到那網頁的原始碼

2017-05-19

根據上篇文章 [C#] 透過 Win32 EnumWindows 和 GetWindowText 取得所有執行程式的hWnd還有標題 我們來抓取到開啟的應用程式,這一篇我們繼續聊聊,抓到開啟的IE 並且抓取開啟網頁的原始碼,其中抓取到IE  的hWnd的部分,可以參考[C#] 透過 Win32 EnumWindows 和 GetWindowText 取得所有執行程式的hWnd還有標題 這篇文章,結果的畫面是長這樣
Image 002

1. 抓取 所有開啟的IE ,根據上篇文章 ,我們只要搜尋 GetWindowText 帶有 Internet Explorer

        private bool ShowIEWindowHandler(int hWnd, int lParam)
        {
            string mystring;

            StringBuilder text = new StringBuilder(255);
            GetWindowText(hWnd, text, 255);

            mystring = text.ToString();
            if (mystring.Contains("Internet Explorer"))
            {
                listBox1.Items.Insert(0, text + "," + hWnd);
                
            }
            return true;
        }

2. 因為我們要抓取該hWnd 其中子項目的 Internet Explorer_Server 類型的hWnd 送指令 取抓取source 轉成 IHTMLDocument 這時候
image

引入win32 介面 :

        [DllImport("user32.dll", EntryPoint = "GetClassNameA")]
        public static extern int GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount);

        /*delegate to handle EnumChildWindows*/
        public delegate int EnumProc(IntPtr hWnd, ref IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern int EnumChildWindows(IntPtr hWndParent, EnumProc lpEnumFunc, ref IntPtr lParam);
        [DllImport("user32.dll", EntryPoint = "RegisterWindowMessageA")]
        public static extern int RegisterWindowMessage(string lpString);
        [DllImport("user32.dll", EntryPoint = "SendMessageTimeoutA")]
        public static extern int SendMessageTimeout(IntPtr hwnd, int msg, int wParam, int lParam, int fuFlags, int uTimeout, out int lpdwResult);
        [DllImport("OLEACC.dll")]
        public static extern int ObjectFromLresult(int lResult, ref Guid riid, int wParam, ref IHTMLDocument2 ppvObject);
        public const int SMTO_ABORTIFHUNG = 0x2;
        public Guid IID_IHTMLDocument = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");

3. 抓取 Internet Explorer_Server class 的 hWnd :

        private int EnumWindows(IntPtr hWnd, ref IntPtr lParam)
        {
            int retVal = 1;
            StringBuilder classname = new StringBuilder(128);
            GetClassName(hWnd, classname, classname.Capacity);
            if ((bool)(string.Compare(classname.ToString(), "Internet Explorer_Server") == 0))
            {
                lParam = hWnd;
                retVal = 0;
            }
            return retVal;
        }

4. 送指令 ,並且轉換成 IHTMLDocument :

        private IHTMLDocument2 documentFromDOM(IntPtr hWnd)
        {


            int lngMsg = 0;
            int lRes;

            EnumProc proc = new EnumProc(EnumWindows);
            EnumChildWindows(hWnd, proc, ref hWnd);
            if (!hWnd.Equals(IntPtr.Zero))
            {
                lngMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
                if (lngMsg != 0)
                {
                    SendMessageTimeout(hWnd, lngMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, out lRes);
                    if (!(bool)(lRes == 0))
                    {
                        int hr = ObjectFromLresult(lRes, ref IID_IHTMLDocument, 0, ref document);
                        if ((bool)(document == null))
                        {
                            MessageBox.Show("CANNOT FOUND IHTMLDocument");

                        }
                    }

                }

            }

            return document;
        }

5.   使用上面的code :

            var document = documentFromDOM(new IntPtr(int.Parse(txtHwnd.Text)));

            if (document != null)
            {
                txtTitle.Text = document.title;
                txtSource.Text = document.body.innerHTML;
            }
            else {
                MessageBox.Show("Sorry I cant fetch it.");
                return;
            }

 

如果有不清楚的地方,這邊提供source code : https://github.com/donma/GetHwndAndGetSourceFromIE

如果有問題直接看code 吧  Smile

reference :http://blog.csdn.net/cz19800823/article/details/11909881


當麻許的超技八 2014 | Donma Hsu Design.