使用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 //即可 ...
随机推荐
- GORM学习指南
orm是一个使用Go语言编写的ORM框架.它文档齐全,对开发者友好,支持主流数据库. 一.初识Gorm Github GORM 中文官方网站内含十分齐全的中文文档,有了它你甚至不需要再继续向下阅读本文 ...
- Centos安装DenyHosts
一.背景 个人申请的腾讯云主机被扫描端口,数百次登录失败的尝试 解决方法:安装工具,记录并屏蔽恶意访问. 二.检查环境 系统安装的sshd是否支持tcp_wrappers(默认都支持) ldd /us ...
- 对飞猪H5端API接口sign签名逆向实验
免责声明 本文章所提到的技术仅用于学习用途,禁止使用本文章的任何技术进行发起网络攻击.非法利用等网络犯罪行为,一切信息禁止用于任何非法用途.若读者利用文章所提到的技术实施违法犯罪行为,其责任一概由读者 ...
- 匿名函数托管 func-spring-boot-starter
匿名函数托管 func-spring-boot-starter 项目地址 func-spring-boot-starter开源项目地址: https://gitee.com/yiur/func-spr ...
- ArrayList实现类
特点 数组结构实现,查询快,增删慢 运行效率高,线程不安全 可重复 常用方法 Modifier and Type Method and Description boolean add(E e) 将指定 ...
- 146_LRU cache | LRU缓存设计
题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...
- HashMap和TreeMap的内部结构
一.HashMap 1.基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hash ...
- go生成随机数字验证码
一行代码搞定 code := fmt.Sprintf("%06v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n( ...
- golang中的channel
1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...
- java-导入import
1 package face_package; 2 3 import face_packagedemoA.DemoA; 4 import face_packagedemoB.DemoB; 5 //真正 ...