2017-08-01 66 views
1

我需要從C++程序中獲取IE中顯示的所有網頁元素。 我試圖用間諜++看,但只有IEFrame。如何從C++程序中檢索DOM元素?

所以我想使用開發工具(在IE中F12),我聽說有一種方法來自動它,一個好主意?

感謝

回答

2

你可以從IE的窗口句柄的IHtmlDocument2參考,甚至退出的進程。這裏記錄在這裏https://support.microsoft.com/en-us/help/249232/how-to-get-ihtmldocument2-from-a-hwnd,但並不真正支持微軟。但是它看起來像今天仍然有效,我已經用Windows 10盒子測試過它,而IE現在是一個冷凍應用程序,所以不會很快改變。

一旦你有適當的Internet Explorer的HWND,比你可以用這樣的代碼得到DOM。確保IE和您的程序在相同的安全級別運行 DOM與編寫IE進程(主機,activex等)時相同,但出於安全原因,某些事情可能不起作用:

void DoSomeDomOperations(HWND hwnd) 
{ 
    UINT msg = RegisterWindowMessage(L"WM_HTML_GETOBJECT"); 
    LRESULT result = 0; 
    SendMessageTimeout(hwnd, msg, NULL, NULL, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR)&result); 
    if (!result) 
     return; 

    // get main document object 
    IHTMLDocument2 *doc = NULL; 
    ObjectFromLresult(result, IID_IHTMLDocument2, NULL, (void**)&doc); 
    if (!doc) 
     return; 

    // get document's url 
    BSTR url = NULL; 
    doc->get_URL(&url); 
    wprintf(L"url:%s\n", url); 
    SysFreeString(url); 

    // get body element 
    IHTMLElement *element = NULL; 
    doc->get_body(&element); 
    if (element) 
    { 
     BSTR text = NULL; 
     element->get_innerText(&text); 
     wprintf(L"text:%s\n", text); 
     SysFreeString(text); 
     element->Release(); 
    } 

    // etc. 
    // etc. 

    doc->Release(); 
} 

這裏是一個全樣本的控制檯應用程序,它可以掃描所有當前IE進程運行:

BOOL CALLBACK GetIEServerWindowProc(HWND hwnd, LPARAM lParam) 
{ 
    // enumerate all child windows to find IE's COM server 
    wchar_t className[100]; 
    GetClassName(hwnd, className, 100); 
    if (!wcscmp(className, L"Internet Explorer_Server")) 
    { 
     *((HWND*)lParam) = hwnd; 
     return FALSE; 
    } 
    return TRUE; 
} 

HWND GetIEServerWindow(HWND hwnd) 
{ 
    HWND serverHwnd = NULL; 
    EnumChildWindows(hwnd, GetIEServerWindowProc, (LPARAM)&serverHwnd); 
    return serverHwnd; 
} 

struct IEServer 
{ 
    DWORD processId; 
    HWND serverHwnd; 
}; 

BOOL CALLBACK GetIEProcessServerWindowProc(HWND hwnd, LPARAM lParam) 
{ 
    DWORD processId = ((IEServer*)lParam)->processId; 
    DWORD pid; 
    GetWindowThreadProcessId(hwnd, &pid); 
    if (pid == processId) 
    { 
     HWND serverHwnd = GetIEServerWindow(hwnd); 
     if (serverHwnd) 
     { 
      ((IEServer*)lParam)->serverHwnd = serverHwnd; 
      return FALSE; 
     } 
    } 
    return TRUE; 
} 

HWND GetIEProcessServerWindow(DWORD processId) 
{ 
    IEServer ie = { processId, NULL }; 
    EnumWindows(GetIEProcessServerWindowProc, (LPARAM)&ie); 
    return ie.serverHwnd; 
} 

void EnumerateIEProcesses() 
{ 
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    if (h == INVALID_HANDLE_VALUE) 
     return; 

    PROCESSENTRY32 process; 
    process.dwSize = sizeof(PROCESSENTRY32); 
    if (Process32First(h, &process)) 
    { 
     do 
     { 
      // we only consider IE processes 
      if (!wcscmp(process.szExeFile, L"iexplore.exe")) 
      { 
       HWND serverHwnd = GetIEProcessServerWindow(process.th32ProcessID); 
       if (serverHwnd) 
       { 
        DoSomeDomOperations(serverHwnd); 
       } 
      } 
     } while (Process32Next(h, &process)); 
    } 
    CloseHandle(h); 
} 

int main() 
{ 
    CoInitialize(NULL); 

    EnumerateIEProcesses(); 
    CoUninitialize(); 
    return 0; 
} 
+0

感謝您簡單等完整的解決方案,它完美的作品! – Entretoize