WebBrowser判断登录成功WebBrowser404错误500错误屏蔽消息窗口Webbrowser判断是否加载成功.docx
《WebBrowser判断登录成功WebBrowser404错误500错误屏蔽消息窗口Webbrowser判断是否加载成功.docx》由会员分享,可在线阅读,更多相关《WebBrowser判断登录成功WebBrowser404错误500错误屏蔽消息窗口Webbrowser判断是否加载成功.docx(11页珍藏版)》请在冰豆网上搜索。

WebBrowser判断登录成功WebBrowser404错误500错误屏蔽消息窗口Webbrowser判断是否加载成功
WebBrowser判断登录成功-WebBrowser-404错误-500错误-屏蔽消息窗口-Webbrowser判断是否加载成功
2011-6-2415:
04:
28ChineseComment(0)Browse(1106)在这里,我来讲讲怎么应付WebBrowser里面的那点破事:
文档真的完成了吗?
也许你和我一样,打开一个页面,听到了不少次的哒哒哒哒的声音,但是单个页面怎么会造成多次的触发DocumentCompleted函数?
不信自己试试,判断文档是否真的完成,需要在这个处理函数内判断ReadyState如下:
privatevoidWebBrowserEx_DocumentCompleted(objectsender
WebBrowserDocumentCompletedEventArgse)
{
if(this.ReadyState==WebBrowserReadyState.Complete)
{
if(null!
=this.Document&&null!
=this.OnDocumentCompleted)
{
this.OnDocumentCompleted(sender,e);
}
}
}
404错误怎么办?
500错误怎么办?
正如你所猜测的,即便是页面浏览错了,在页面中还是会显示内容,还是会无耻的触发DocumentCompleted事件,那么怎么判断到底是404页面还是500页面呢?
看招:
SHDocVw.WebBrowsersw=this.ActiveXInstanceasSHDocVw.WebBrowser;
sw.NavigateError+=sw_NavigateError;
//-----------------------------------------
voidsw_NavigateError(objectpDisp,refobjectURL,refobjectFrame
refobjectStatusCode,refboolCancel)
{
ErrorCodeserrorcode=ErrorCodes.HTTP_STATUS_BAD_REQUEST;
foreach(ErrorCodesecodeinEnum.GetValues(typeof(ErrorCodes)))
{
if(((long)ecode)==(Int32)StatusCode)
{
errorcode=ecode;
break;
}
}
System.Console.WriteLine("Error"+URL+">>"+errorcode);
}
上面的代码中存在一个很丑陋的转换Enum的操作,我懒得修改了,这个枚举是俺自己定义的,定义的就是错误的名字信息,如下:
1:
publicenumErrorCodes:
long
2:
{
3:
HTTP_STATUS_BAD_REQUEST=400,
4:
HTTP_STATUS_DENIED=401,
5:
HTTP_STATUS_PAYMENT_REQ=402,
6:
HTTP_STATUS_FORBIDDEN=403,
7:
HTTP_STATUS_NOT_FOUND=404,
8:
HTTP_STATUS_BAD_METHOD=405,
9:
HTTP_STATUS_NONE_ACCEPTABLE=406,
10:
HTTP_STATUS_PROXY_AUTH_REQ=407,
11:
HTTP_STATUS_REQUEST_TIMEOUT=408,
12:
HTTP_STATUS_CONFLICT=409,
13:
HTTP_STATUS_GONE=410,
14:
HTTP_STATUS_LENGTH_REQUIRED=411,
15:
HTTP_STATUS_PRECOND_FAILED=412,
16:
HTTP_STATUS_REQUEST_TOO_LARGE=413,
17:
HTTP_STATUS_URI_TOO_LONG=414,
18:
HTTP_STATUS_UNSUPPORTED_MEDIA=415,
19:
HTTP_STATUS_RETRY_WITH=449,
20:
HTTP_STATUS_SERVER_ERROR=500,
21:
HTTP_STATUS_NOT_SUPPORTED=501,
22:
HTTP_STATUS_BAD_GATEWAY=502,
23:
HTTP_STATUS_SERVICE_UNAVAIL=503,
24:
HTTP_STATUS_GATEWAY_TIMEOUT=504,
25:
HTTP_STATUS_VERSION_NOT_SUP=505,
26:
27:
INET_E_INVALID_URL=0x800C0002L,
28:
INET_E_NO_SESSION=0x800C0003L,
29:
INET_E_CANNOT_CONNECT=0x800C0004L,
30:
INET_E_RESOURCE_NOT_FOUND=0x800C0005L,
31:
INET_E_OBJECT_NOT_FOUND=0x800C0006L,
32:
INET_E_DATA_NOT_AVAILABLE=0x800C0007L,
33:
INET_E_DOWNLOAD_FAILURE=0x800C0008L,
34:
INET_E_AUTHENTICATION_REQUIRED=0x800C0009L,
35:
INET_E_NO_VALID_MEDIA=0x800C000AL,
36:
INET_E_CONNECTION_TIMEOUT=0x800C000BL,
37:
INET_E_INVALID_REQUEST=0x800C000CL,
38:
INET_E_UNKNOWN_PROTOCOL=0x800C000DL,
39:
INET_E_SECURITY_PROBLEM=0x800C000EL,
40:
INET_E_CANNOT_LOAD_DATA=0x800C000FL,
41:
INET_E_CANNOT_INSTANTIATE_OBJECT=0x800C0010L,
42:
INET_E_REDIRECT_FAILED=0x800C0014L,
43:
INET_E_REDIRECT_TO_DIR=0x800C0015L,
44:
INET_E_CANNOT_LOCK_REQUEST=0x800C0016L,
45:
INET_E_USE_EXTEND_BINDING=0x800C0017L,
46:
INET_E_TERMINATED_BIND=0x800C0018L,
47:
INET_E_INVALID_CERTIFICATE=0x800C0019L,
48:
INET_E_CODE_DOWNLOAD_DECLINED=0x800C0100L,
49:
INET_E_RESULT_DISPATCHED=0x800C0200L,
50:
INET_E_CANNOT_REPLACE_SFP_FILE=0x800C0300L,
51:
INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY=0x800C0500L,
52:
INET_E_CODE_INSTALL_SUPPRESSED=0x800C0400L,
53:
}
Winform的WebBrowser居然不自己定义错误值,真是一个半成品啊。
让内部的Html调用的JS可以使用外部提供的C#类的函数
做起来简单。
首先生成一个类(第一行不能少)
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
publicclassA
{
publicStringFun()
{
returnGuid.NewGuid().ToString();
}
}
构造WebBrowser的时候设置属性ObjectForScripting=newA();
页面中使用类似如下的代码(注意函数名为window.external):
<ahref="javascript:
{alert(window.external.Fun());}">测试按钮</a>
赶紧试试吧
事件调用转换成过程调用
需求是这样的,我需要做一个模拟的操作界面,包括:
登录,打开特定页面,填写内容,提交几步。
在事件模型之下,我需要先调用Navigate函数,
然后在DocumentCompleted的处理函数中处理每个的返回内容,这样很麻烦,能不能使用一个函数将事件处理直接屏蔽掉
(SynchronizedNavigate),我的操作转换成:
SynchronizedNavigate(登录页面)填写登录信息模拟点击登录按钮SynchronizedNavigate(数据填充页面)填写页面内容提交到服务器取得返回页面校验实际输入的值
是不是很玄妙,其实很简单(注意不能缺少函数Application.DoEvents())
1:
publicvoidSynchronizedNavigate(StringstrUrl)
2:
{
3:
this.Navigate(strUrl);
4:
WaitNavigatingDone();
5:
}
6:
7:
publicvoidWaitNavigatingDone()
8:
{
9:
while(m_isDocumentationCompleted==false)
10:
{
11:
Application.DoEvents();
12:
Thread.Sleep(50);
13:
}
14:
}
怎么屏蔽内部的消息窗口?
直接看代码,很无耻滴注册了函数进去
privatevoidWebBrowserEx_Navigated(objectsender,WebBrowserNavigatedEventArgse)
{
if(this.Document==null||this.Document.DomDocument==null)
{
return;
}
mshtml.IHTMLDocument2doc2=this.Document.DomDocumentasmshtml.IHTMLDocument2;
if(this.BlockClientMessage)
{
if(null!
=doc2&&null!
=doc2.parentWindow)
{
//blockalertandconfirm
doc2.parentWindow.execScript(@"functionalert(){}functionconfirm(){returntrue;}"
"javaScript");
}
}
}
怎么屏蔽网页内部弹出内容到新窗口?
也许你可以使用Navigate的变种,里面有voidNavigate(stringurlString,boolnewWindow)和Navigate(Uriurl,boolnewWindow)这两个函数,俺没有仔细试过,我使用的是COM接口:
this.Navigate("about:
blank");
SHDocVw.WebBrowsersw=this.ActiveXInstanceasSHDocVw.WebBrowser;
if(null!
=sw)
{
sw.NewWindow3+=newSHDocVw.DWebBrowserEvents2_NewWindow3EventHandler(sw_NewWindow3);
}
----------------------
voidsw_NewWindow3(refobjectppDisp,refboolCancel,uintdwFlags,stringbstrUrlContext,stringbstrUrl)
{
if(null==OnNewWindow&&this.BlockPopWindow)
{
Cancel=true;
this.Navigate(bstrUrl);
}
elseif(null!
=OnNewWindow)
{
OnNewWindow(this,bstrUrl,refCancel);
}
}
自定义协议?
你是不是想玩玩在<a
href=”personal:
//username=1235”>用户信息</a>的点击的时候弹出一个内部的页面,而不是默认的
Http访问?
实现类似的协议很简单,在_Navigating(objectsender,
WebBrowserNavigatingEventArgs
e)这个事件处理中处理即可:
当碰到您的协议的时候,e.Cancel=true;然后生成HTML,设置DocumentText就完成了。
取得当前的选择的文本
publicstringSelectedText
{
get
{
IHTMLDocument2doc=(IHTMLDocument2)this.Document.DomDocument;
IHTMLTxtRangetxt=(IHTMLTxtRange)doc.selection.createRange();
returntxt.htmlText;
}
}
高亮指定的文本
1:
publicvoidHilightText(stringkeyword,intnindexK)
2:
{
3:
if(null==keyword||
4:
keyword.Trim().Length<1||
5:
null==this.Document||
6:
this.Document.DomDocument==null||
7:
this.IsBusy||
8:
this.IsDisposed
9:
)
10:
{
11:
return;
12:
}
13:
HTMLDocumentdocument=(HTMLDocument)this.Document.DomDocument;
14:
IHTMLDOMNodebodyNode=(IHTMLDOMNode)this.Document.Body.DomElement;
15:
HilightText(document,bodyNode,keyword.Trim(),nindexK);
16:
}
17:
18:
privatevoidHilightText(HTMLDocumentdocument,IHTMLDOMNodenode,stringkeyword,intnindexK)
19:
{
20:
//nodeType=3:
text节点
21:
if(node.nodeType==3)
22:
{
23:
stringnodeText=node.nodeValue.ToString();
24:
//如果找到了关键字
25:
if(nodeText.Contains(keyword))
26:
{
27:
IHTMLDOMNodeparentNode=node.parentNode;
28:
//将关键字作为分隔符,将文本分离,并逐个添加到原text节点的父节点
29:
string[]result=nodeText.Split(newstring[]{keyword},StringSplitOptions.None);
30:
for(inti=0;i<result.Length-1;i++)
31:
{
32:
if(result[i]!
="")
33:
{
34:
IHTMLDOMNodetxtNode=document.createTextNode(result[i]);
35:
parentNode.insertBefore(txtNode,node);
36:
}
37:
IHTMLDOMNodeorgNode=document.createTextNode(keyword);
38:
IHTMLDOMNodehilightedNode=(IHTMLDOMNode)document.createElement("SPAN");
39:
IHTMLStylestyle=((IHTMLElement)hilightedNode).style;
40:
style.color="black";
41:
style.backgroundColor=colorTables[nindexK%colorTables.Length];
42:
hilightedNode.appendChild(orgNode);
43:
44:
parentNode.insertBefore(hilightedNode,node);
45:
}
46:
if(result[result.Length-1]!
="")
47:
{
48:
IHTMLDOMNodepostNode=document.createTextNode(result[result.Length-1]);
49:
parentNode.insertBefore(postNode,node);
50:
}
51:
parentNode.removeChild(node);
52:
}//EndofnodeText.Contains(keyword)
53:
}
54:
else
55:
{
56:
//如果不是text节点,则递归搜索其子节点
57:
IHTMLDOMChildrenCollectionchildNodes=node.childNodesasIHTMLDOMChildrenCollection;
58:
foreach(IHTMLDOMNodeninchildNodes)
59:
{
60:
HilightText(document,n,keyword,nindexK);
61:
}
62:
}
63:
}
作者:
桂林熙熙发表于2011-06-2421:
11