WPF/WinForm中加载网页的几种方式及如何加载Flash库(WebBrowser/CEF)

前言

Webview2官方文档:

https://docs.microsoft.com/zh-cn/microsoft-edge/webview2/get-started/wpf

WPF加载网页的三种方式

  • WebBrowser IE内核
  • CEFSharp Chrome内核(三方库)
  • Webview2 Chrome内核(官方库)

CEFSharp:

https://www.psvmc.cn/article/2021-10-29-wpf-cefsharp.html

Webview2 :

WebView2未来应该是要替代WebBrowser的,虽然需要依赖本机自带的Edge chromium内核,但相信未来的windows 更新肯定会以Edge chromium内核代替IE内核,并且不需要重新下载Chrome浏览器,使用Edge也会有一样的浏览体验。而作为桌面开发人员来说,使用WebView2直接加载网页会比使用CefSharp来得更舒服,不再需要引入一堆的CEF类库,同时安装文件也会缩小很多。

Flash支持测试页面

https://sc.chinaz.com/donghua/220315391630.htm

准备工作

FlashPlayer

https://www.flash.cn/download-wins

其实我们不同的浏览器使用到的DLL是不同的

Windows

image-20220319210437869

Chrome

image-20220319210729463

FireFox

image-20220319210554079

所以我们可以根据自己的需求去安装,不用全部安装到PC上。

Flash的现状

  • IE安装插件还可以使用

  • 360极速及QQ浏览器等,这些浏览器一般都是双内核,其中的Chromium内核版本一般都比较低,所以还可以继续加载Flash Player来使用,啥时候这些国产浏览器升级内核到88及以上版本,就彻底不支持了

获取系统IE版本

获取浏览器内核版本

https://www.psvmc.cn/zjtools/z/browserinfo/index.html

不要用下面这个地址,测试的不准确

https://ie.icoa.cn/

网上有这么个说法

WebBrowser使用的浏览器版本是IE7,这个说法其实是不太准确的。

应该这样说

WebBrowser使用的是系统版本的IE对应的兼容模式。

比如Win10的是IE11,对应的兼容模式是IE7。

所以我在Win10上用下面两种方式获取到的IE版本都是11。

方式1

1
2
3
4
5
6
7
8
9
10
/// <summary>
/// 获取IE版本号
/// </summary>
/// <returns>
/// </returns>
public static int GetMajorVersion()
{
//通过WebBrowser方案获取版本号
return new WebBrowser().Version.Major;
}

方式2

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
/// <summary>
/// IE浏览器版本号帮助类
/// </summary>
public static class IEVersionHelper
{
/// <summary>
/// 获取IE主版本号
/// </summary>
/// <returns>
/// </returns>
public static string GetMajorVersion()
{
var majorVersion = string.Empty;

var detailVersion = GetDetailVersion();
if (!string.IsNullOrWhiteSpace(detailVersion))
{
if (detailVersion.IndexOf(".", StringComparison.Ordinal) is int connectedCharFirstIndex && connectedCharFirstIndex > -1)
{
majorVersion = detailVersion.Substring(0, connectedCharFirstIndex);
}
else
{
majorVersion = detailVersion;
}
}

return majorVersion;
}

/// <summary>
/// 获取IE详细版本号
/// </summary>
/// <returns>
/// </returns>
public static string GetDetailVersion()
{
string text = @"SOFTWARE\Microsoft\Internet Explorer";
//通过注册表获取用户IE版本号
RegistryKey mainKey = Registry.LocalMachine;
RegistryKey subKey = mainKey.OpenSubKey(text);

var versionNumber = subKey?.GetValue("svcVersion")?.ToString() ?? string.Empty;
if (string.IsNullOrEmpty(versionNumber))
{
versionNumber = subKey?.GetValue("svcUpdateVersion")?.ToString() ?? string.Empty;
if (string.IsNullOrEmpty(versionNumber))
{
versionNumber = subKey?.GetValue("Version")?.ToString() ?? string.Empty;
}
}
return versionNumber;
}
}

或者

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
public static int GetCurrSystemIEVersion()
{
try
{
RegistryKey mreg;
mreg = Registry.LocalMachine;
mreg = mreg.OpenSubKey(@"Software\Microsoft\Internet Explorer\");
string IEVersion = (string)mreg.GetValue("svcVersion");
if (IEVersion == null)
{
IEVersion = (string)mreg.GetValue("Version");
}
mreg.Close();
if (IEVersion.StartsWith("8"))
{
return 8;
}
if (IEVersion.StartsWith("9"))
{
return 9;
}
if (IEVersion.StartsWith("10"))
{
return 10;
}
if (IEVersion.StartsWith("11"))
{
return 11;
}
return 0;
}
catch (Exception)
{
return 0;
}
}

注册表的生效规则

设置IE版本

当前用户配置

1
2
3
4
# 32位
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
# 64位
HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

本机配置

1
2
3
4
# 32位
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
# 64位
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

设置IE GPU加速

当前用户配置

1
2
3
4
# 32位
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_GPU_RENDERING
# 64位
HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_GPU_RENDERING

本机配置

1
2
3
4
# 32位
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_GPU_RENDERING
# 64位
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_GPU_RENDERING

32位和64位注册表的生效规则

系统 软件 生效的注册表
32 位 32 位 HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
64 位 64 位 HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
64 位 32 位 HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
32 位 64 位 无法将 64 位版本的 Office 安装在 32 位版本的 Windows

注意

  1. HKEY_LOCAL_MACHINE 中设置的优先级要高于 HKEY_CURRENT_USER
  2. 建议配置HKEY_CURRENT_USERHKEY_LOCAL_MACHINE可能没有权限而报错。

注册表修改的两种方式

方式1

1
2
3
string fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
string fcRegKey32 = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_GPU_RENDERING";
Registry.SetValue(fcRegKey32, fileName, version, RegistryValueKind.DWord);

方式2

1
2
3
4
5
6
7
8
9
10
11
12
string fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
RegistryKey mreg;
mreg = Registry.CurrentUser;
mreg = mreg.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl");
RegistryKey m = mreg.OpenSubKey("FEATURE_GPU_RENDERING", true);
if (m != null)
{
m.SetValue(fileName, version, RegistryValueKind.DWord);
m.Close();
}
mreg.Flush();
mreg.Close();

注意

推荐方式1

注册表设置IE版本

记录WebBrowser控件使用IE渲染版本的路径:

注意

注册表不要修改HKEY_LOCAL_MACHINE下的,因为可能没有权限而导致修改失败。

工具类1

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
public class WebBrowserHelper
{
public static int GetCurrSystemIEVersion()
{
try
{
RegistryKey mreg;
mreg = Registry.LocalMachine;
mreg = mreg.OpenSubKey(@"Software\Microsoft\Internet Explorer\");
string IEVersion = (string)mreg.GetValue("svcVersion");
if (IEVersion == null)
{
IEVersion = (string)mreg.GetValue("Version");
}
mreg.Close();
if (IEVersion.StartsWith("8"))
{
return 8;
}
if (IEVersion.StartsWith("9"))
{
return 9;
}
if (IEVersion.StartsWith("10"))
{
return 10;
}
if (IEVersion.StartsWith("11"))
{
return 11;
}
return 0;
}
catch (Exception)
{
return 0;
}
}

/// <summary>
/// 32系统32位程序或64位系统上64位程序的注册表
/// </summary>
/// <param name="version"></param>
/// <returns></returns>
public static bool SetIEVersionInSys32(int version)
{
try
{
if (version < 8)
{
return false;
}
int v = 8888;
if (version == 9)
{
v = 9999;
}
if (version >= 10)
{
v = 10001;
}
if (version >= 11)
{
v = 11001;
}

string fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
string rkIEVersion32 = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
string rkIEGPU32 = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_GPU_RENDERING";
Registry.SetValue(rkIEVersion32, fileName, v, RegistryValueKind.DWord);
Registry.SetValue(rkIEGPU32, fileName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception)
{
}
return false;
}

/// <summary>
/// 64位系统上32程序的注册表
/// </summary>
/// <param name="version"></param>
/// <returns></returns>
public static bool SetIEVersionInSys64(int version)
{
if (version < 8)
{
return false;
}
try
{
int v = 8888;
if (version == 9)
{
v = 9999;
}
if (version >= 10)
{
v = 10001;
}

if (version >= 11)
{
v = 11001;
}
string fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
string rkIEVersion = @"HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
string rkIEGPU = @"HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_GPU_RENDERING";
Registry.SetValue(rkIEVersion, fileName, v, RegistryValueKind.DWord);
Registry.SetValue(rkIEGPU, fileName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception) { }
return false;
}

/// <summary>
/// 设置为计算机上的最新IE版本
/// </summary>
/// <returns></returns>
public static bool SetWebBrowserLastVersion()
{
int version = GetCurrSystemIEVersion();
bool f1 = SetIEVersionInSys32(version);
bool f2 = SetIEVersionInSys64(version);

if (f1 || f2)
{
return true;
}

return false;
}

/// <summary>
/// 设置WebBrowser对应的IE版本
/// </summary>
/// <param name="version"></param>
/// <returns></returns>
public static bool SetWebBrowserVersion(int version)
{
bool f1 = SetIEVersionInSys32(version);
bool f2 = SetIEVersionInSys64(version);

if (f1 || f2)
{
return true;
}

return false;
}
}

工具类2

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
public class IEHelper
{
/// <summary>
/// 定义IE版本的枚举
/// </summary>
public enum IeVersion
{
ie11强制,//11001 (0x2AF9) IE11
ie11,//11000 (0x2AF8) IE11
ie10强制,//10001 (0x2711) IE10
ie10,//10000 (0x02710) IE10
ie9强制,//9999 (0x270F) IE9
ie9,//9000 (0x2328) IE9.
ie8强制,//8888 (0x22B8) IE8. 强制IE8标准模式显示,忽略!DOCTYPE指令
ie8,//8000 (0x1F40) IE8. 默认设置,在IE8标准模式中按照网页上!DOCTYPE指令展示网页
ie7//7000 (0x1B58) 使用WebBrowser Control控件的应用程序所使用的默认值,在IE7标准模式中按照网页上!DOCTYPE指令来展示网页
}

/// <summary>
/// 设置WebBrowser的默认版本
/// </summary>
/// <param name="ver">
/// IE版本
/// </param>
public static void SetIE(IeVersion ver)
{
//获取程序名称
//string productName = AppDomain.CurrentDomain.SetupInformation.ApplicationName;
string productName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
object version;
switch (ver)
{
case IeVersion.ie7:
version = 0x1B58;
break;

case IeVersion.ie8:
version = 0x1F40;
break;

case IeVersion.ie8强制:
version = 0x22B8;
break;

case IeVersion.ie9:
version = 0x2328;
break;

case IeVersion.ie9强制:
version = 0x270F;
break;

case IeVersion.ie10:
version = 0x2710;
break;

case IeVersion.ie10强制:
version = 0x2711;
break;

case IeVersion.ie11:
version = 0x2AF8;
break;

case IeVersion.ie11强制:
version = 0x2AF9;
break;

default:
version = 0x1F40;
break;
}
string fcRegKey32 = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
string fcRegKey64 = @"HKEY_CURRENT_USER\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
Registry.SetValue(fcRegKey32, productName, version, RegistryValueKind.DWord);
if (Environment.Is64BitOperatingSystem)
{
Registry.SetValue(fcRegKey64, productName, version, RegistryValueKind.DWord);
}
}
}

调用

1
2
3
4
5
6
7
int version = GetMajorVersion();
Console.WriteLine("version:" + version);

if (version >= 9)
{
IEHelper.SetIE(IEHelper.IeVersion.ie9);
}

注意

网上有这么个说法,把版本设置为非IE的版本号,会使用Edge,这个说法是错误的。

虽然更改后加载检测浏览器内核的网页上显示是Edge,但是其实上并不是使用的Edge。

WOW6432Node其实不是64位程序的配置,而是64位系统32位程序使用到的配置。

Registry.SetValue方法会自动创建不存在的路径和值。

WebBrowser

WPF下的WebBrowser存在内存泄漏的问题,所以这里用WinForm实现。

WebBrowser调用的就是本机IE浏览器,并且WebBrowser默认就是运行在IE7 mode下。

添加Falsh插件

有些老的系统必须用IE执行的,就只能用WebBrowser了。

保证IE上能运行Flash只需要安装flashplayerax_install_cn.exe就可以了。

首先我们要判断Flash有没有安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private bool checkFlashInstall()
{
Type type = Type.GetTypeFromProgID("ShockwaveFlash.ShockwaveFlash");
if (type == null)
{
return false;
}

object flashObject = Activator.CreateInstance(type);
string versionString = flashObject
.GetType()
.InvokeMember("GetVariable", BindingFlags.InvokeMethod, null, flashObject, new object[] { "$version" }) as string;

Console.WriteLine("Flash版本:" + versionString);
Marshal.ReleaseComObject(flashObject);
return true;
}

安装EXE程序

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
private void installEXE(string fileName, string arguments)
{
string result = "";
try
{
using (Process process = new Process())
{
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false; // 要获取输出,此值必须为 false。
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;

process.Start();
process.WaitForExit(); // 等待执行完毕
result = process.StandardError.ReadToEnd(); // 获取输出值
process.Close();
}
}
catch (Exception ex)
{
result = ex.Message;
}

Console.WriteLine("result:" + result);
}

注意

安装成功或退出,result返回的字符串都是空字符串。

判断并安装

1
2
3
4
5
6
7
8
9
10
private void Form1_Load(object sender, EventArgs e)
{
bool isInstallFlash = checkFlashInstall();
if (!isInstallFlash)
{
installEXE("./Libs/flashplayerax_install_cn.exe", "");
}

extendedWebBrowser1.Url = new Uri(url);
}

窗口弹出

当页面中打开新页面的方式是window.open的时候,默认的行为是调用系统的IE打开,这样就会出现一个问题,打开的IE页面是读取不到我们页面的cookie数据的,导致登录失效。

所以解决的方法是

  1. 获取弹出页面的网址
  2. 本窗口打开或者新窗口打开

那么怎么获取到弹出页面的网址呢?

默认的WebBrowser新打开的窗口会用系统默认的IE打开,并且我们也没法获取新窗口的地址自行处理。

所以我们自定义WebBrowser保证能获取新窗口的地址。

自定义ExtendedWebBrowser

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
119
120
121
122
123
124
125
using System;

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

public event EventHandler BeforeNavigate;

public event EventHandler BeforeNewWindow;

[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);
}

//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();
}

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;
}

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;
}

//This class will capture events from the WebBrowser
private class WebBrowserExtendedEvents : System.Runtime.InteropServices.StandardOleMarshalObject, DWebBrowserEvents2
{
private 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);
}
}
}

public class WebBrowserExtendedNavigatingEventArgs : System.ComponentModel.CancelEventArgs
{
private string _Frame;
private string _Url;

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

public string Frame
{
get { return _Frame; }
}

public string Url
{
get { return _Url; }
}
}
}

回到Form1.cs[设计]窗口,在菜单生成中,点生成解决方案

一会之后在工具箱的最上方就会出现一个新的组件ExtendedWebBrowser,把ExtendedWebBrowser拖进来。

ExtendedWebBrowser的事件里双击BeforeNewWindow并添加代码:

本窗口打开

1
2
3
4
5
6
private void extendedWebBrowser1_BeforeNewWindow(object sender, EventArgs e)
{
WebBrowserExtendedNavigatingEventArgs eventArgs = e as WebBrowserExtendedNavigatingEventArgs;
eventArgs.Cancel = true;
((ExtendedWebBrowser)sender).Navigate(eventArgs.Url);
}

或者

新窗口打开

1
2
3
4
5
6
7
8
private void extendedWebBrowser1_BeforeNewWindow(object sender, EventArgs e)
{
WebBrowserExtendedNavigatingEventArgs eventArgs = e as WebBrowserExtendedNavigatingEventArgs;
eventArgs.Cancel = true;
Form1 form1 = new Form1();
form1.url = eventArgs.Url;
form1.Show();
}

WinForm显示模糊的解决办法

WinForm 对高分辨率屏幕的适配并不是很好,当分辨率较高时,Windows 系统会将程序里面的字体进行缩放,在 Windows 10 系统尤其严重,这将导致程序的界面大小变化,字体也会变得模糊。

以下两种方法任选其一即可。

方法1

我们用WebBrowser加载的网页,会看起来有点模糊,设置DPI设置的问题,解决方法如下:

Form的属性设置如下

将 Form 的 AutoScaleMode 属性设置为 DPI

image-20220326151909358

在 Program.cs 中添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
private static void Main()
{
//添加的代码
if (Environment.OSVersion.Version.Major >= 6)
{
SetProcessDPIAware();
}

//原代码
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

//添加的代码
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
}

方法2

知道了导致程序模糊的原因,找到相应的解决方法就很简单了,我们只需要让程序感知 DPI ,当 DPI 较高时禁止 Windows 对其进行自动缩放。

注意事项:该方法适用于 .NET Framework 版本大于等于4.5的程序。

右键项目,添加应用程序清单文件

image-20220326153520407

把其中的下面的代码部分解除注释:

1
2
3
4
5
6
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>

在程序配置文件(app.config)的appSettings节点下添加如下代码

1
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />

结果大致如下

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
</configuration>

CEF加载Flash

找到本地flash的dll(pepflashplayer.dll)

项目中新建plugins,添加pepflashplayer.dll,右击属性,改为始终复制

CEF初始化配置

1
2
3
4
5
CefSettings settings = new CefSharp.CefSettings()
settings.CefCommandLineArgs["enable-system-flash"] = "1";
settings.CefCommandLineArgs.Add("ppapi-flash-version", "32.0.0.171");
settings.CefCommandLineArgs.Add("ppapi-flash-path", @"plugins\pepflashplayer.dll");
Cef.Initialize(settings);