使用IWebBrowser2操控浏览器页面测试(IE)
测试一下在IE浏览器界面中插入代码测试,采用寻找窗口的方式获取Internet Explorer_Server
句柄。
写的时候参考了很多网上的资料,有些地方不大适用就稍微修改了一下。
- SendMessageTimeout函数一直无效(看网上有一回答说
c#
可以正常使用,没试过),无效情况是执行成功(非超时),但是lpRes为0,于是改用SendMessage;- 使用spyxx查找
IEFrame
下的Internet Explorer_Server
窗口,根据实际情况来寻找窗口,网上年代久远的部分代码只有三层;- 似乎是因为
main
函数在退出时会释放程序执行过程中申请的所有资源的原因,在程序最后加上CoUninitialize()将导致win7下出现程序退出异常的情况,在win10下则不会;另一个解决办法是在CoUninitialize()
后边使用ExitProcess()退出进程,但是可能有部分内存未释放;- 测试代码时,在win7及以下平台系统中
navigate2()
方法无法使用,应使用navigate()
,使用navigate()时BSTR
类型的URL
参数时使用SysAllocString初始化,虽然实际上是wchar*,但是使用常量初始化变量或者使用字符串拷贝函数wcscpy
时会出错(迷);- QueryService参数中的
SID_SWebBrowserApp
替换为IID_IWebBrowserApp
。
这里将js代码写入页面需要运行的话,我是使用IHTMLDocument2
的write
方法写回document
,页面刷新执行js代码,但是页面部分样式可能丢失。除此之外,还有很多方法可以实现,比如利用事件响应等方法,而且也不一定插入js,插入iframe或者一条链接之类的无需刷新页面。
#include "windows.h"
#include "mshtml.h"
#include "stdio.h"
#include "ExDisp.h"
#include "atlbase.h"
#include "comutil.h"
#include "oleacc.h"
//#pragma comment(lib, "oleacc.lib")
//int WINAPI WinMain(HINSTANCE hins, HINSTANCE hPrev, LPSTR lpCmdLine, INT nCmdShow) {
INT main(int argc, char* argv[]){
//IWebBrowser2
HWND hWnd_pre = NULL, hWnd_child = NULL, hWnd_IES = NULL;
hWnd_pre = FindWindow("IEFrame", NULL); //IE Window Class
if (hWnd_pre == NULL) {
OutputDebugString(TEXT("IE didnot open."));
}
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Shell DocObject View"), NULL); // test
if (hWnd_child == NULL) { // not only three Layers
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Frame Tab"), NULL);
if (hWnd_child == NULL) {
OutputDebugString(TEXT("not Found IE Tab."));
}
hWnd_pre = hWnd_child;
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("TabWindowClass"), NULL);
hWnd_pre = hWnd_child;
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Shell DocObject View"), NULL);
hWnd_pre = hWnd_child;
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Internet Explorer_Server"), NULL);
}
else {
hWnd_pre = hWnd_child;
hWnd_child = FindWindowEx(hWnd_pre, 0, TEXT("Internet Explorer_Server"), NULL);
}
hWnd_IES = hWnd_child; // Get Internet Explorer_Server Window's Handle
printf("handle value of Internet Explorer_Server => %#x\n", (DWORD*)hWnd_child);
CoInitialize(0); // for using of COM interfaces
UINT nMsg = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT")); // register common msg of between two windows
if (nMsg)
printf("success registe Window message WM_HTML_GETOBJECT, msg ID => %#x\n", nMsg);
CComPtr<IHTMLDocument2> pHtmlDoc;
LRESULT result;
//if (!SendMessageTimeout(hWnd_IES, nMsg, 0, 0, SMTO_NORMAL, 30000, (LPDWORD)result)) {
if (!(result = SendMessage(hWnd_IES, nMsg, 0, 0))) // send message for associated value of msg
printf("call sendMessageTimeout failed:( error code: %#x\n", GetLastError());
else {
printf("returned result value: %#x\n", result);
/*if (!result) {
printf("returned result id none...end");
ExitProcess(1);
}*/
HMODULE hLib = LoadLibrary("oleacc.dll");
LPFNOBJECTFROMLRESULT pFObjectFromLresult = (LPFNOBJECTFROMLRESULT)GetProcAddress(hLib, "ObjectFromLresult");
//HRESULT hRes = ObjectFromLresult(result, IID_IHTMLDocument2, 0, (void**)&pHtmlDoc);
HRESULT hRes = pFObjectFromLresult(result, IID_IHTMLDocument2, 0, (void**)&pHtmlDoc);
if (SUCCEEDED(hRes)) {
printf("get IHTMLDocument2 success :)\n");
//OLECHAR urll[] = L"http://www.baidu.com/";
CComPtr<IHTMLWindow2> spWnd2;
CComPtr<IServiceProvider> spServiceProvider;
IWebBrowser2* pWebBrow = NULL;
hRes = pHtmlDoc->get_parentWindow((IHTMLWindow2**)&spWnd2);
if (SUCCEEDED(hRes)) {
hRes = spWnd2->QueryInterface(IID_IServiceProvider, (void**)&spServiceProvider); // Query Interface
if (SUCCEEDED(hRes)) {
hRes = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&pWebBrow); // query service
if (SUCCEEDED(hRes)) {
printf("Get IWebBrowser handlw Success :)\n");
////1-跳转测试
//VARIANT PARAM;
//VariantInit(&PARAM);
////V_VT(&PARAM) = VT_I4;
////V_I4(&PARAM) = navOpenInNewTab; //open in new tab
////hRes = pWebBrow->Navigate2(&CComVariant("http://www.baidu.com/"), 0, 0, 0, 0);// win7 and former versions not support.
//BSTR URLL = SysAllocString(L"http://www.baidu.com/");
//hRes = pWebBrow->Navigate(URLL, &PARAM, &PARAM, &PARAM, &PARAM); // navigate
//SysFreeString(URLL);
//if (SUCCEEDED(hRes)) printf("navigate success :)\n");
//else printf("navigate failed :(\n");
///*//2-获取地址栏URL测试
//hRes = pWebBrow->get_LocationURL(&URLLL);
//if(SUCCEEDED(hRes))
// printf("Get URL : %ws\n", URLL);*/
////3-write document
//SAFEARRAY* pSafeArr = SafeArrayCreateVector(VT_VARIANT, 0, 1);
//if (pSafeArr) {
// BSTR pInsertCode = SysAllocString(L"<script>alert('just a test')</script>");
// VARIANT *PARAM = NULL;
// SafeArrayAccessData(pSafeArr, (void**)&PARAM);
// V_VT(PARAM) = VT_BSTR; // PARAM->vt = VT_BSTR
// V_BSTR(PARAM) = pInsertCode; // PARAM->bStrVal
// SafeArrayUnaccessData(pSafeArr);
// pHtmlDoc->write(pSafeArr); // will refresh
// pHtmlDoc->close();
// SafeArrayDestroy(pSafeArr);
// pSafeArr = NULL;
//}
//get HTML codes
BSTR pText = SysAllocString(L"<script>alert('test')</script>");
BSTR wheer = SysAllocString(L"afterBegin"); //代码放置位置
CComPtr<IHTMLElement> pHtmlElem;
pHtmlDoc->get_body(&pHtmlElem);
//pHtmlElem->get_innerHTML(&pText);
//pHtmlElem->put_innerHTML(pText);
hRes = pHtmlElem->insertAdjacentHTML(wheer, pText); // 插入
SysFreeString(pText);
SysFreeString(wheer);
pText = NULL;
wheer = NULL;
//重载页面
if (SUCCEEDED(hRes)) {
printf("insert html code SUCCESS:)\n");
/*pHtmlElem->get_outerHTML(&pText);
SAFEARRAY* pSafeArr = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT *PARAM = NULL;
SafeArrayAccessData(pSafeArr, (void**)&PARAM);
V_VT(PARAM) = VT_BSTR;
V_BSTR(PARAM) = pText;
SafeArrayUnaccessData(pSafeArr);
pHtmlDoc->write(pSafeArr);
pHtmlDoc->close();
SafeArrayDestroy(pSafeArr);
pSafeArr = NULL;*/
}
else
printf("insert html code Failed:(\n");
//printf("HTML Text (length: %#x): %ws\n", );
//INT dwSize = wcslen(pText);
//CHAR *pOutter = (CHAR*)malloc(dwSize);
//WideCharToMultiByte(CP_ACP, 0, pText, dwSize, pOutter, dwSize, 0, 0);
//FILE *fp = fopen("html.html", "w");
////fprintf(fp, "%ws", pText);
//fwrite(pOutter, wcslen(pText), 1, fp);
//free(pOutter);
//fclose(fp);
}
else printf("Get IWebBrowser handle Failed:(\n");
}
//pHtmlDoc->get_body(&pHtmlElem); //get_body(&pHtmlElem);
//pHtmlElem->get_outerHTML(pText); //get_innerText(pText);
//printf("GOT > \n%ws\n", pText);
pWebBrow->Release();
pWebBrow = NULL;
}
else
printf("error returned Result Code: %#x\n", hRes);
}
else printf("get IHTMLDocument2 failed:(\n");
}
/*printf("%#x\n", hwd);
PostMessage(hWnd_IES, WM_QUIT, 0, 0);
PostMessage(hWnd_IES, WM_CLOSE, 0, 0);
PostMessage(hWnd_IES, WM_DESTROY, 0, 0);*/
/*CoUninitialize(); //添加则出现异常,可能是在程序退出时还会调用一次析构函数,以释放所有声明的变量
ExitProcess(0);*/
}
愈发感觉windows的不简单。
参考链接:
- MSDN
- 获取IWebBrowser2指针的方法
使用IWebBrowser2操控浏览器页面测试(IE)的更多相关文章
- Web前端页面的浏览器兼容性测试心得(二)搭建原汁原味的IE8测试环境
如果你做的页面被老板或PM要求兼容IE8,你就值得同情了.IE8不支持HTML5,在2017年的前端界,开发者不涉及HTML5标准简直寸步难行.然而,有一个可怕的事实客观存在,那就是IE8是Win7系 ...
- Selenium基础之--01(将浏览器最大化,设置浏览器固定宽、高,操控浏览器前进、后退)
1,将浏览器最大化 我们知道调用启动的浏览器不是全屏的,这样不会影响脚本的执行,但是有时候会影响我们"观看"脚本的执行. coding=utf-8 from selenium im ...
- BrowserSync - 浏览器同步测试工具
背景: 之前在学gulp的时候,使用gulp-livereload来实时自动刷新页面省时开发,但一直比较难用,现在找到新的替代神器. 安装: // 使用淘宝镜像会快些 npm install -g ...
- 省时的浏览器同步测试工具 browsersync NodeJS
http://www.browsersync.cn/ 省时的浏览器同步测试工具 Browsersync能让浏览器实时.快速响应您的文件更改(html.js.css.sass.less等)并自动刷新页面 ...
- Web浏览器兼容性测试工具如何选择
对于前端开发工程师来说,网页兼容性测试工程师而言,确保代码在各种主流浏览器的各个版本中都能正常工作是件很费时的事情,幸运的是,有很多优秀的工具可以帮助测试浏览器的兼容性,领测软件测试网向您推荐12款很 ...
- 在线HTTP速度测试(响应时间测试)及浏览器兼容测试
一.前言 网站的响应时间,是判断一个网站是否是好网站的重要的因素之一.百度首页的响应时间在全国各个省份小于10ms.这个响应时间远远好于竞争对手.根据美丽说的技术负责人分析,美丽说访问速度提升10%, ...
- mac安装浏览器同步测试工具
1.安装node.js (1)打开终端,输入以下命令安装Homebrew ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebre ...
- Selenium_python自动化跨浏览器执行测试
Selenium_python自动化跨浏览器执行测试(简单多线程案例) 转:https://www.cnblogs.com/dong-c/p/8976746.html 跨浏览器测试是功能测试的一个分 ...
- 浏览器页面区域大小的js获取方法
浏览器页面区域大小的获取: /在IE.FireFox.Opera下都可以使用 document.body.clientWidth document.body.clientHeight //即可 ...
随机推荐
- 微信小程序组建通信
子组件传递父组件需要用到triggerEvent方法,当子组件(自定义组件)点击button的时候调用triggerEvent方法传递一些数据,首先第一个属性为自定义名称(myevent)对应父组件( ...
- nginx配置指定域名访问,nginx禁止ip访问,配置空主机头 syscal
1.大家有过这方面的困扰,就是自己的网站给其他人恶意域名解析到自己的服务器ip上. 特别不爽,那大家可以用用空主机头的方法. 先给大家看下我的nginx.conf配置 http { log_forma ...
- Java带包结构调用命令行运行编译
原文: https://www.toutiao.com/i6491809562037846542/ 带包结构调用命令行运行编译. 记事本编写两个简单的类 文件结构目录 启动DOS,进入文件所在目录 分 ...
- XRecyclerView:实现下拉刷新、滚动到底部加载更多以及添加header功能的RecyclerView
介绍: 一个实现了下拉刷新,滚动到底部加载更多以及添加header功能的的RecyclerView.使用方式和RecyclerView完全一致,不需要额外的layout,不需要写特殊的adater. ...
- DASCTF-Sept-X-浙江工业大学秋季挑战赛-pwn-wp
目录 DASCTF-Sept-X-浙江工业大学秋季挑战赛-pwn-wp 总结 datasystem check分析 漏洞点 利用思路 exp hehepwn 漏洞点 exp hahapwn 漏洞点 e ...
- Java异常理解之Exception in thread “main“ java.lang.ArrayIndexOutOfBoundsException
这个异常是Java中的数组越界问题 当你使用不合法的索引访问数组是会出现这种错误例如: class Solution { public static int climbStairs(int n) { ...
- 【记录一个问题】go.mod中使用replace后,编译出现神奇的错误:
biz\child.go:5:2: imported and not used: "xxx.com/start/common/src/polaris" as biz biz\chi ...
- Manacher算法求解回文字符串
Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...
- unity3d之sokect通信
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using S ...
- Prometheus-operator 介绍和配置解析
随着云原生概念盛行,对于容器.服务.节点以及集群的监控变得越来越重要.Prometheus 作为 Kubernetes 监控的事实标准,有着强大的功能和良好的生态.但是它不支持分布式,不支持数据导入. ...