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


    使用场景

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

    遇到问题

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

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

    解决办法

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

    static class WebBrowserEx
    {
    	#region 浏览器设置
    	///   
    	/// 修改注册表信息来兼容当前程序  
    	///   
    	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);
    	}
    
    	///   
    	/// 获取浏览器的版本  
    	///   
    	///   
    	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;
    	}
    
    	///   
    	/// 通过版本得到浏览器模式的值  
    	///   
    	///   
    	///   
    	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;
    	}
    
    	/// 
    	/// 查询系统环境是否支持IE8以上版本
    	/// 
    	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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    通过获取到的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

  • 相关阅读:
    【 C++ 】set、multiset的介绍和使用
    蒸汽流量计量表
    戏说领域驱动设计(十九)——外验
    狄克斯特拉(Dijkstra) 算法 php实现
    Clickhouse数据库部署、Python3压测实践
    【图像去噪】基于边缘增强扩散 (cEED) 和 Coherence Enhancing Diffusion (cCED) 滤波器实现图像去噪附matlab代码
    【C/C++】malloc/free 和 new/delete
    Java - equals 与 == 的区别
    聚焦关键要素|打造智慧园区综合运营决策平台解决方案
    大语言模型(一)OLMo
  • 原文地址:https://blog.csdn.net/qq_39827640/article/details/127732305