给Webbrowser 添加用户脚本
最近越来越懒,以免将来忘记了,记录之。把代码贴上了,忽略了框架跨域问题,要是在乎跨域的话,就看看这个吧:
http://blog.wahahajk.com/2010/10/c-webbrowseriframe.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace Ice
{
public class IceBrowser : IDisposable
{
#region ------Fields------
private readonly WebBrowser browser;
private bool isNewWindowEnabled;
private static readonly Random random = new Random();
#endregion
#region ------Methods------
/// <summary>
/// 创建一个 IceBrowser
/// </summary>
/// <param name="browser">WebBrowser 控件</param>
/// <param name="scripting">用于在 javascript 中调用的 .NET 对象</param>
/// <param name="isNewWindowEnabled">是否允许鼠标点击的超链接在新窗口中打开, 如果为 false, 则新窗口在当前 WebBrowser 中打开</param>
public IceBrowser( WebBrowser browser, object scripting=null, bool isNewWindowEnabled=false ) {
if (null == browser) {
throw new ArgumentNullException( "browser", "浏览器控件不能为空" );
}
this.browser = browser;
this.isNewWindowEnabled = isNewWindowEnabled;
this.Scripting = scripting;
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler( this.browserDocumentCompleted );
//browser.Navigated += new WebBrowserNavigatedEventHandler(this.browserNavigated);
browser.NewWindow += new CancelEventHandler( this.browserNewWindow );
}
private void browserDocumentCompleted( object sender, WebBrowserDocumentCompletedEventArgs e ) {
if (e.Url.ToString().EndsWith( "#" ) || e.Url.ToString().Equals( "about:blank" ) || e.Url.ToString().Contains( "res://ieframe.dll" )) {
return;
}
if (e.Url.ToString() != this.browser.Url.ToString()) {
foreach (HtmlWindow frame in this.browser.Document.Window.Frames) {
try {
if (e.Url.ToString().Equals( frame.Url.ToString() )) {
InstallScript( UserJS, frameDoc: frame.Document );
return;
}
}
catch { }
}
return;
}
else {
InstallScript( UserJS );
return;
}
}
private void browserNewWindow( object sender, CancelEventArgs e ) {
if (!this.isNewWindowEnabled) {
e.Cancel = true;
this.browser.Navigate( this.browser.StatusText );
}
}
/// <summary>
/// 在 WebBrowser子框架中增加 script 标签, 并添加定义的javascript代码 或 指定脚本的地址
/// </summary>
/// <param name="code">javascript 代码</param>
/// <param name="url">脚本地址, 如: "http://www.google.com/xxx.js"</param>
/// <param name="frameDoc">将加入代码的框架</param>
public void InstallScript( string code = "", Uri url = null, HtmlDocument frameDoc = null ) {
HtmlDocument doc = frameDoc;
if (frameDoc == null) {
doc = this.browser.Document;
}
HtmlElement newElement = null;
newElement = doc.CreateElement( "script" );
//newElement.SetAttribute( "id", MakeKey() );
newElement.SetAttribute( "type", "text/javascript" );
newElement.SetAttribute( "language", "javascript" );
if (url==null)
newElement.SetAttribute( "text", code );
else
newElement.SetAttribute( "src", url.AbsoluteUri );
try {
doc.GetElementsByTagName( "head" )[0].AppendChild( newElement );
}
catch { }
}
public void ExecuteScript( string code, HtmlDocument doc ) {
HtmlElement newElement = null;
newElement = doc.CreateElement( "script" );
//newElement.SetAttribute( "id", MakeKey() );
newElement.SetAttribute( "type", "text/javascript" );
newElement.SetAttribute( "language", "javascript" );
newElement.SetAttribute( "text", code );
try {
doc.GetElementsByTagName( "head" )[0].AppendChild( newElement );
}
catch { }
}
/// <summary>
/// 生成一个随机的脚本 id
/// </summary>
/// <returns>脚本 id</returns>
private static string MakeKey() {
string key = DateTime.Now.ToString( "yyyyMMddhhmmss" ) + random.Next( 0, 0x7fffffff );
return string.Format( "script_{0}", key );
}
#endregion
#region ------Properties------
public HtmlDocument Document {
get {
return this.browser.Document;
}
}
public bool IsNewWindowEnabled {
get {
return this.isNewWindowEnabled;
}
set {
this.isNewWindowEnabled = value;
}
}
public object Scripting {
set {
this.browser.ObjectForScripting = value;
}
}
public string Url {
get {
if (null == this.browser.Url) {
return string.Empty;
}
return this.browser.Url.AbsoluteUri.ToLower();
}
}
public string UserJS { get; set; }
#endregion
#region IDisposable 成员
public void Dispose() {
throw new NotImplementedException();
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace Ice
{
public class IceBrowser : IDisposable
{
#region ------Fields------
private readonly WebBrowser browser;
private bool isNewWindowEnabled;
private static readonly Random random = new Random();
#endregion
#region ------Methods------
/// <summary>
/// 创建一个 IceBrowser
/// </summary>
/// <param name="browser">WebBrowser 控件</param>
/// <param name="scripting">用于在 javascript 中调用的 .NET 对象</param>
/// <param name="isNewWindowEnabled">是否允许鼠标点击的超链接在新窗口中打开, 如果为 false, 则新窗口在当前 WebBrowser 中打开</param>
public IceBrowser( WebBrowser browser, object scripting=null, bool isNewWindowEnabled=false ) {
if (null == browser) {
throw new ArgumentNullException( "browser", "浏览器控件不能为空" );
}
this.browser = browser;
this.isNewWindowEnabled = isNewWindowEnabled;
this.Scripting = scripting;
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler( this.browserDocumentCompleted );
//browser.Navigated += new WebBrowserNavigatedEventHandler(this.browserNavigated);
browser.NewWindow += new CancelEventHandler( this.browserNewWindow );
}
private void browserDocumentCompleted( object sender, WebBrowserDocumentCompletedEventArgs e ) {
if (e.Url.ToString().EndsWith( "#" ) || e.Url.ToString().Equals( "about:blank" ) || e.Url.ToString().Contains( "res://ieframe.dll" )) {
return;
}
if (e.Url.ToString() != this.browser.Url.ToString()) {
foreach (HtmlWindow frame in this.browser.Document.Window.Frames) {
try {
if (e.Url.ToString().Equals( frame.Url.ToString() )) {
InstallScript( UserJS, frameDoc: frame.Document );
return;
}
}
catch { }
}
return;
}
else {
InstallScript( UserJS );
return;
}
}
private void browserNewWindow( object sender, CancelEventArgs e ) {
if (!this.isNewWindowEnabled) {
e.Cancel = true;
this.browser.Navigate( this.browser.StatusText );
}
}
/// <summary>
/// 在 WebBrowser子框架中增加 script 标签, 并添加定义的javascript代码 或 指定脚本的地址
/// </summary>
/// <param name="code">javascript 代码</param>
/// <param name="url">脚本地址, 如: "http://www.google.com/xxx.js"</param>
/// <param name="frameDoc">将加入代码的框架</param>
public void InstallScript( string code = "", Uri url = null, HtmlDocument frameDoc = null ) {
HtmlDocument doc = frameDoc;
if (frameDoc == null) {
doc = this.browser.Document;
}
HtmlElement newElement = null;
newElement = doc.CreateElement( "script" );
//newElement.SetAttribute( "id", MakeKey() );
newElement.SetAttribute( "type", "text/javascript" );
newElement.SetAttribute( "language", "javascript" );
if (url==null)
newElement.SetAttribute( "text", code );
else
newElement.SetAttribute( "src", url.AbsoluteUri );
try {
doc.GetElementsByTagName( "head" )[0].AppendChild( newElement );
}
catch { }
}
public void ExecuteScript( string code, HtmlDocument doc ) {
HtmlElement newElement = null;
newElement = doc.CreateElement( "script" );
//newElement.SetAttribute( "id", MakeKey() );
newElement.SetAttribute( "type", "text/javascript" );
newElement.SetAttribute( "language", "javascript" );
newElement.SetAttribute( "text", code );
try {
doc.GetElementsByTagName( "head" )[0].AppendChild( newElement );
}
catch { }
}
/// <summary>
/// 生成一个随机的脚本 id
/// </summary>
/// <returns>脚本 id</returns>
private static string MakeKey() {
string key = DateTime.Now.ToString( "yyyyMMddhhmmss" ) + random.Next( 0, 0x7fffffff );
return string.Format( "script_{0}", key );
}
#endregion
#region ------Properties------
public HtmlDocument Document {
get {
return this.browser.Document;
}
}
public bool IsNewWindowEnabled {
get {
return this.isNewWindowEnabled;
}
set {
this.isNewWindowEnabled = value;
}
}
public object Scripting {
set {
this.browser.ObjectForScripting = value;
}
}
public string Url {
get {
if (null == this.browser.Url) {
return string.Empty;
}
return this.browser.Url.AbsoluteUri.ToLower();
}
}
public string UserJS { get; set; }
#endregion
#region IDisposable 成员
public void Dispose() {
throw new NotImplementedException();
}
#endregion
}
}
作者:一修先生
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。