C# WebBrowser无法跳转默认浏览器问题

使用场景

使用WebBrowser只是为了做内嵌页展示,内嵌页内容链接要跳转系统默认浏览器。

遇到问题

1.非ui主线程打开的WebBrowser加载的网页内容链接无法跳转
2.非链接标签无法跳转,如下button标签

<button class="container" onclick="clickTwo()">
function clickOne() {
  // 按钮1链接
  var link1 = 'https://xxx'
  clickEvent(link1, '按钮1')
}

解决办法

WebBrowser控件的内核为IE,默认为IE7,很多的网站不支持IE7,所以需要使用WebBrowser的话,对WebBrowser提升内核还是很有必要的。
下面通过修改注册表信息来兼容当前程序的方式可以解决第二个问题。

static class WebBrowserEx
{
	#region 浏览器设置
	/// <summary>  
	/// 修改注册表信息来兼容当前程序  
	/// </summary>  
	private static void SetWebBrowserFeatures(int ieVersion)
	{
		if (LicenseManager.UsageMode != LicenseUsageMode.Runtime)
			return;
		//获取程序及名称  
		var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
		//得到浏览器的模式的值  
		uint ieMode = GetEmulationMode(ieVersion);
		var featureControlRegKey = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\";
		//设置浏览器对应用程序(appName)以什么模式(ieMode)运行  
		Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION",
			appName, ieMode, RegistryValueKind.DWord);
		//不晓得设置有什么用  
		Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION",
			appName, 1, RegistryValueKind.DWord);
	}

	/// <summary>  
	/// 获取浏览器的版本  
	/// </summary>  
	/// <returns></returns>  
	public static int GetBrowserVersion()
	{
		int browserVersion = 0;
		using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer",
			RegistryKeyPermissionCheck.ReadSubTree,
			System.Security.AccessControl.RegistryRights.QueryValues))
		{
			var version = ieKey.GetValue("svcVersion");
			if (null == version)
			{
				version = ieKey.GetValue("Version");
				if (null == version)
					throw new ApplicationException("Microsoft Internet Explorer is required!");
			}
			int.TryParse(version.ToString().Split('.')[0], out browserVersion);
		}
		//如果小于7  
		if (browserVersion < 7)
		{
			throw new ApplicationException("不支持的浏览器版本!");
		}
		return browserVersion;
	}

	/// <summary>  
	/// 通过版本得到浏览器模式的值  
	/// </summary>  
	/// <param name="browserVersion"></param>  
	/// <returns></returns>  
	public static uint GetEmulationMode(int browserVersion)
	{
		UInt32 mode = 11000; // Internet Explorer 11
		switch (browserVersion)
		{
			case 7:
				mode = 7000; // Internet Explorer 7
				break;
			case 8:
				mode = 8000; // Internet Explorer 8
				break;
			case 9:
				mode = 9000; // Internet Explorer 9
				break;
			case 10:
				mode = 10000; // Internet Explorer 10.  
				break;
			case 11:
				mode = 11000; // Internet Explorer 11  
				break;
		}
		return mode;
	}

	/// <summary>
	/// 查询系统环境是否支持IE8以上版本
	/// </summary>
	public static bool IfWindowsSupport()
	{
		bool isWin7 = Environment.OSVersion.Version.Major > 6;
		bool isSever2008R2 = Environment.OSVersion.Version.Major == 6
			&& Environment.OSVersion.Version.Minor >= 1;

		if (!isWin7 && !isSever2008R2)
		{
			return false;
		}
		else return true;
	}

	public static void SetIEVersion()
	{
		int ieVersion = GetBrowserVersion();
		if (IfWindowsSupport())
		{
			SetWebBrowserFeatures(ieVersion < 11 ? ieVersion : 11);
		}
		else
		{
			// 如果不支持IE8 则修改为当前系统的IE版本
			SetWebBrowserFeatures(ieVersion < 7 ? 7 : ieVersion);
		}
	}
	#endregion
}

WebBrowser内嵌页内容链接默认使用IE浏览器打开,如果要跳转系统默认浏览器,需要能够获取跳转的链接才能指定默认浏览器打开。需要重新封装WebBrowser来获取跳转Url。

public class WebBrowserExtendedNavigatingEventArgs : CancelEventArgs
{
	private string _Url;
	public string Url
	{
		get { return _Url; }
	}

	private string _Frame;
	public string Frame
	{
		get { return _Frame; }
	}

	public WebBrowserExtendedNavigatingEventArgs(string url, string frame)
		: base()
	{
		_Url = url;
		_Frame = frame;
	}
}

public class ExtendedWebBrowser : System.Windows.Forms.WebBrowser
{
	System.Windows.Forms.AxHost.ConnectionPointCookie cookie;
	WebBrowserExtendedEvents events;

	//This method will be called to give you a chance to create your own event sink
	protected override void CreateSink()
	{
		//MAKE SURE TO CALL THE BASE or the normal events won't fire
		base.CreateSink();
		events = new WebBrowserExtendedEvents(this);
		cookie = new System.Windows.Forms.AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(DWebBrowserEvents2));
	}

	protected override void DetachSink()
	{
		if (null != cookie)
		{
			cookie.Disconnect();
			cookie = null;
		}
		base.DetachSink();
	}

	//This new event will fire when the page is navigating
	public event EventHandler BeforeNavigate;
	public event EventHandler BeforeNewWindow;

	protected void OnBeforeNewWindow(string url, out bool cancel)
	{
		EventHandler h = BeforeNewWindow;
		WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, null);
		if (null != h)
		{
			h(this, args);
		}
		cancel = args.Cancel;
	}

	protected void OnBeforeNavigate(string url, string frame, out bool cancel)
	{
		EventHandler h = BeforeNavigate;
		WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, frame);
		if (null != h)
		{
			h(this, args);
		}
		//Pass the cancellation chosen back out to the events
		cancel = args.Cancel;
	}

	//This class will capture events from the WebBrowser
	class WebBrowserExtendedEvents : System.Runtime.InteropServices.StandardOleMarshalObject, DWebBrowserEvents2
	{
		ExtendedWebBrowser _Browser;
		public WebBrowserExtendedEvents(ExtendedWebBrowser browser) { _Browser = browser; }

		//Implement whichever events you wish
		public void BeforeNavigate2(object pDisp, ref object URL, ref object flags, ref object targetFrameName, ref object postData, ref object headers, ref bool cancel)
		{
			_Browser.OnBeforeNavigate((string)URL, (string)targetFrameName, out cancel);
		}

		public void NewWindow3(object pDisp, ref bool cancel, ref object flags, ref object URLContext, ref object URL)
		{
			_Browser.OnBeforeNewWindow((string)URL, out cancel);
		}

	}

	[System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),
	System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch),
	System.Runtime.InteropServices.TypeLibType(System.Runtime.InteropServices.TypeLibTypeFlags.FHidden)]
	public interface DWebBrowserEvents2
	{

		[System.Runtime.InteropServices.DispId(250)]
		void BeforeNavigate2(
			[System.Runtime.InteropServices.In,
			System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp,
			[System.Runtime.InteropServices.In] ref object URL,
			[System.Runtime.InteropServices.In] ref object flags,
			[System.Runtime.InteropServices.In] ref object targetFrameName, [System.Runtime.InteropServices.In] ref object postData,
			[System.Runtime.InteropServices.In] ref object headers,
			[System.Runtime.InteropServices.In,
			System.Runtime.InteropServices.Out] ref bool cancel);
		[System.Runtime.InteropServices.DispId(273)]
		void NewWindow3(
			[System.Runtime.InteropServices.In,
			System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp,
			[System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref bool cancel,
			[System.Runtime.InteropServices.In] ref object flags,
			[System.Runtime.InteropServices.In] ref object URLContext,
			[System.Runtime.InteropServices.In] ref object URL);
	}
}
ExtendedWebBrowser web;
private void Form1_Load(object sender, EventArgs e)
{
	WebBrowserEx.SetIEVersion();
	web = new ExtendedWebBrowser();
	web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Wb_DocumentCompleted);
	web.NewWindow += new CancelEventHandler(webBrowser_NewWindow);
	web.BeforeNewWindow += new EventHandler(webBrowser_BeforeNewWindow);
	web.ScriptErrorsSuppressed = true;
	web.Url = new Uri(uri); 
	web.Dock = DockStyle.Fill;
	this.Controls.Add(web);
}

private void Wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}

private void webBrowser_NewWindow(object sender, CancelEventArgs e)
{
	e.Cancel = true;
}

private void webBrowser_BeforeNewWindow(object sender, EventArgs e)
{
	WebBrowserExtendedNavigatingEventArgs eventArgs = e as WebBrowserExtendedNavigatingEventArgs;
	System.Diagnostics.Process.Start(eventArgs.Url);
}

通过获取到的url跳转到默认浏览器,上面的两个问题得到解决。

参考

https://www.cnblogs.com/sung/p/3391264.html
https://blog.csdn.net/sinat_32232885/article/details/52182180
https://blog.csdn.net/sunjilonggood/article/details/103885575

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值