桌面客户端也叫 PC 客户端,桌面操作系统(如Windows、MacOS、Ubuntu 等系统)上的软件都可以称为桌面客户端软件,客户端软件的开发有多种技术选型方式,而且每种方式各有优劣。

采用不同的方式通常会导致在开发周期、技术人员招聘、软件性能、安装包体积等方面有比较大的差别。本文结合我这些年的客户端开发经验,聊一聊在客户端开发方面的各种技术选型以及他们的优劣。

一、技术方案汇总

1.1 WinForms

WinForms(Windows Forms)是微软推出的 UI 框架,可以使用 C# 和 Visual Basic 作为开发语言。

WinForms 框架适合开发传统 UI 元素和界面的应用程序,比如工业、医疗领域的管理、控制软件。

当然,WinForms 也能开发出绚丽、非标准化的界面效果,但需要花费较多的时间,对开发人员的技术要求也更高。

基于 WinForms 开发的应用程序需要依赖.Net Framework 运行时,如果用户电脑上未安装.Net Framework 运行时,软件安装包需要自带运行时,并自动为用户安装,否则程序会无法运行。

使用 WinForms 开发的应用程序体积本身很小,但为了适应不同的用户电脑环境,安装包需要检测用户电脑上的.Net Framework 运行时版本是否与软件所需版本匹配,如果不匹配则需要自动安装相应的.Net Framework 运行时。

.Net Framework 很难做成便携版,通常需要使用微软提供的安装包进行安装,安装.Net Framework 运行时分为在线和离线安装两种方式:

  • 离线安装方式。
    将微软提供的.Net Framework 离线安装包(不同版本体积不同,如 4.8 版本的离线安装包约 115M 左右)打包进程序安装包,安装时进行释放和安装。这种方式会增加程序安装包的体积。
  • 在线安装方式。
    将微软提供的.Net Framework 在线安装工具(体积很小,约 1.5M 左右)打包进程序安装包,安装时进行释放和在线安装,这种方式虽然可以减少安装包体积,但在线安装需要实时从微软服务器下载资源,受限于用户网络环境,很可能会安装失败。

1.1.1 .Net Framework 版本兼容性

在.Net Framework 4.5 版本之前,其各个版本之间不相互兼容(无论是向前还是向后都无法兼容),但从 4.5 及以后的版本就可以保证向后兼容了。

举例说明:

  • 如果程序使用.Net Framework 3.5 版本开发,则只能基于该版本的运行时运行。
  • 如果程序使用.Net Framework 4.6 版本开发,则用户电脑上只需要安装>=4.6 版本的运行时即可运行。

1.1.2 系统自带.Net Framework 版本

从 Windows Vista 开始,Windows 系统会自带.Net Framework 运行时,但各个系统自带的运行时版本不同。

下表列出了不同系统自带的.Net Framework 运行时的最低版本:

为什么是最低版本了?
因为用户可能通过系统升级的方式更新了.Net Framework 运行时的版本。

操作系统 .Net Framework 运行时版本
Windows XP 1.0
Windows Vista 2.0
Windows 7 3.5
Windows 8 4.5
Windows 10 4.6 ~ 4.7
Windows 11 4.8+

不同系统所支持的.Net Framework 最高版本也有所不同:

  • Windows XP 最高支持.NET Framework 4.0
  • Windows 7 最高支持.NET Framework 4.6.2
  • Windows 8.1 最高支持.NET Framework 4.6.2
  • Windows 10 和 Windows 11 可以支持任意版本的.NET Framework

1.1.3 .Net Core

.Net Core 官网:

https://dotnet.microsoft.com/en-us/

.Net Core 是微软开发的一个开源的、跨平台的(支持 Windows、MacOS、Linux 等系统)通用软件开发框架。在.Net Core 出现之前,开发人员只能基于.Net Framwork 开发 WinForms 应用程序,.Net Core 出现之后,开发人员多了一种选择。

.Net Core 与.Net Framework 最大的不同在于.Net Core 是开源和跨平台的,基于.Net Core 开发的应用程序可以运行在不同的操作系统上,如 Windows、Linux、MacOS。

.Net Core 还处于快速的更新迭代中,之前的老版本对 WinForms 及 WPF 的支持不太好(甚至不支持),建议采用最新版本的.Net Core 进行开发。

使用.Net Core 开发的应用的体积本身非常小,但在打包分发时也需要携带.Net Core 运行时。不同于.Net Framework,.Net Core 运行时既支持安装包的方式,也支持便携版的方式。

以.Net Core 6.0 版本为例,微软官方提供的 WindowsDesktop 的运行时大小为 50M,我们可以根据程序实际依赖情况,安装包只包含程序依赖的文件,从而缩减安装包体积(缩减后约 20M 左右)。

1.2 WPF

WPF(Windows Presentation Foundation)也是微软推出的 UI 框架。与 WinForms 一样,可以使用 C#和 Visual Basic 语言进行开发,WPF也支持.Net Framework 和.Net Core 两种开发平台。

使用 WPF 框架开发的应用程序界面更加炫酷,界面组件可随意定制化,适合用于对界面要求较高的应用。

WPF 程序的性能稍逊与 WinForms 应用,不过这种性能差别在计算机硬件性能快速提升的今天已在逐渐的被淡化,因此在进行技术选型时基本可以忽略的 WPF 性能问题了。

需要注意的是,WPF 应用在启动时通常较慢,比如用户打开应用后需要花费大概 1 秒左右的时间才能看见主界面。

1.3 MFC

MFC(Microsoft Foundation Classes)是微软提供的一个基础类库,对 Windows 系统 API 进行了封装,包含一些基础控件,从而减少应用开发人员的工作量。
MFC 应用程序的开发语言为 C++,MFC 提供的控件都是常规的 Windows 风格,和 WinForms 一样,如果需要开发炫丽、交互复杂的界面,需要开发人员花费精力自己绘制,会降低不少开发效率。

MFC 比较适合应用在对软件性能要求较高、调用系统 API 较多、界面交互较简单的软件上。

小知识:MFC又被戏称为“麻烦C”,大抵是因为用它开发界面比较麻烦吧。

1.4 DirectUI

DirectUI 是一类技术的统称,即 Paint on parent dc directly,直接在父窗体上进行绘制。该技术是对 MFC 的一种改进,使用DirectUI开发的界面,整个窗口只有一个句柄,而不是像 MFC 一样,每个控件都有一个句柄。

目前流行的 DirectUI 界面库大多由个人开发并开源,由于没有专门的团队进行维护,因此使用该类界面库的公司通常需要自己维护一个分支进行 Bug 修复和添加新功能。

常用的 DirectUI 界面库有:

建议选择公司技术人员比较熟悉的DirectUI库,最好能熟悉源码,可以进行 Bug 修复和功能定制开发。

DirectUI 界面库通常都是轻量级的,因此其开发的应用程序体积都会比较小。

1.5 Qt

Qt 是一个跨平台的 C++图像界面开发框架,不仅支持 Windows、MacOS、Linux 等 PC 操作系统,还支持嵌入式 QNX、VxWorks 及 Android、iOS 等操作系统。

Qt 的应用非常广泛,是目前使用最广的 C++ 图像界面框架。Qt 应用程序的开发语言为 C++,Qt 比 MFC 上手更快,而且在控件定制、 UI 绘制上也比 MFC 方便。

以 Qt 5.15.2 版本为例,Qt 应用程序打包后的体积最小到 6MB 左右,如果使用更老版本的 Qt,体积还可以更小。

1.5.1 Qt 版权问题

Qt 分为开源版本和商业版本,开源版本可以免费使用,商业版本需要付费才能使用。

开源版本既可以免费使用也可以用于商业用途,但需要遵守相应的规则。Qt中的大多数模块采用LGPL开源协议,少部分模块采用的是GPL协议,在开发商业软件是我们应选择LGPL协议的模块,并采用Qt动态链接库的方式(而不是静态库的方式)。

对应有些必须静态链接的模块,如QtMain,Qt采用BSD协议,允许在商业软件中使用。

慎用采用GPL协议的模块,该协议具有传染性,它要求所有使用这些模块的软件都要开源,因此要慎用GPL协议的模块。

可以在 https://www.qt.io/product/features 网站查询Qt模块对应的开源协议。

另外如果有对 Qt 源码进行修改,需要公布修改部分的源码。

1.5.2 Qt 版本选择

Qt 5.6版本是Qt最后一个支持Windows XP的版本,而Qt 6 也不再支持Windows 7及其以下的版本。

另外,从Qt 6版本开始,官方不在提供32位的预编译二进制文件。

1.6 CEF

CEF 官网:

https://bitbucket.org/chromiumembedded/cef/wiki/Home

CEF(Chromium Embedded Framework )是 Google 公司开发的一个跨平台的浏览器内核框架(号称与 Chrome 浏览器为同一内核),以开源库的方式提供,可以内嵌到第三方程序中用于显示网页以及与网页进行交互。

CEF 自身主要使用 C++进行开发,目前也有 CEF 的其他语言的绑定,比如 CefSharp 就是 C# 的绑定。因此基于 CEF 技术方案,可以使用 C++、C#或其他语言作为开发语言,但据我了解大多使用的还是 C++。

在开发中,我们通常不会直接使用 CEF,而是进行二次封装,将其封装成组件,该组件用于打开 Web 页面,由 Web 页面负责界面交互,并通过Javascript 和 C++或 C#交互。

CEF 虽然是作为一个库来提供的,但其接口却及其复杂难用(像一坨屎一样),目前还没有一个对其封装的比较好的库,包括我自己硬着头皮封装的 QCefWidget 也不是那么完善,也有一些小问题。

CEF 经历了 CEF1 和 CEF3 两个大版本,CEF1 现已基本被淘汰,目前主流的是 CEF3(CEF 2623 版本是最后一个支持 Windows XP 的版本)。

由于版权问题,CEF 默认不支持 MP4 解码,如需支持,需要自行下载源码进行编译(这个过程可能会耗时 1 天左右)。

亦可以使用我编译好的CEF:https://github.com/winsoft666/cef_binary

采用 CEF 内嵌 Web 页面的方式,虽然可以借助 Web 开发的优势,极大提升软件开发效率,Web 页面更新起来也比客户端的升级更加方便,但由于其本质还是客户端内嵌浏览器,因此软件内存占用会比较高,通常一个简单的程序可能会占用 100MB 左右内存。在性能方面,也远远不及上面介绍的其他原生开发方式。

CEF 不同版本的体积差距较大,2623 版本压缩后大约 25MB,而 89.0.18 版本压缩后大约 60MB。不同版本对 Web 新特效的支持程度不同,在不在乎安装包体积的情况下可以选择最新版本,如果需要考虑安装包体积,则需要做出权衡。

采用该技术方案需要由 Web 开发者开发客户端内嵌页面,C++开发者开发客户端主体框架。由于 Web 页面无法直接访问系统资源,因此还需 Web 与 C++进行交互,并由 C++完成系统功能的开发。

1.7 Microsoft WebView2

微软基于 Chromium 开源项目开发了Edge浏览器,同时也提供了 WebView2 组件,基于该组件可以实现在客户端中嵌入Web页面,实现 JavaScript 和本地程序的相互调用。

WebView2 组件支持 Windows7 及以上平台,但 Windows7 系统肯定是没有自带该组件的,需要单独下载安装。如果用户有更新过 Windows 10、11系统,很可能系统已集成组件,不需要额外下载安装。

Microsoft WebView2 的接口使用起来比 CEF 舒爽多了。

1.8 Electron

前面提到使用 CEF 时需要二次封装,而 CEF 的接口又不是那么易于使用,所以封装一个功能完整、稳定运行的 CEF 组件需要花费不少时间。Electron 则是基于 CEF 进行了深层次的封装,Electron 相比自己封装 CEF 会更加稳定,还可以节省开发和后期维护的时间。

Electron 和 CEF 最大的不同之处是 Electron 可以直接调用 Node.js 的模块,如文件、系统、网络等模块,基于这些模块,理论上可以使用 JavaScript 完成客户端应用的开发,但这也仅限于理论上,实际上大多数的 Web 开发者缺少客户端软件开发经验,甚至缺少系统方面的理论基础,因此很难完全依靠 Web 开发者开发出功能完备的客户端软件。

基于 Electron 开发客户端时,大多数时候还需要 C++开发者开发 Node 模块来供 JavaScript 调用。

1.9 其他图像界面库

除了上面介绍的方案,还要很多其他的优秀界面库,这些库各有特色,目前它们的使用者还没有上面的多。

下面列举了一些我所知道的优秀界面库,欢迎补充:

二、选型建议

在进行技术选型时,需要综合考虑客户端需要支持的系统环境、安装包大小、界面效果、动画性能、开发周期、技术人员储备等因素,通常没有标准答案。

下面根据几种常见的情况,给出了一点点建议,仅供参考。

  • 如果程序只需要支持 Windows 平台,对安装包大小不敏感,开发周期想要尽可能缩短,可以选择 Microsoft WebView2、 WinForms、 WPF。

  • 如果程序只需要支持 Windows 平台,对安装包大小比较敏感,可以选择 MFC、DirectUI、Qt。

  • 如果程序只需要支持 Windows 平台,对安装包大小比较敏感,界面效果要求较高,开发周期想要尽可能缩短,可以选择 Microsoft WebView2。

  • 如果程序需要支持 Windows、macOS 平台,对安装包大小不敏感,开发周期想要尽可能缩短,建议选择 Electron。

  • 如果程序需要支持 Windows、macOS 平台,对安装包大小比较敏感,可以选择 Qt。

  • 如果程序需要支持国产系统(如麒麟系统、统信系统等),可能只能选择 Qt 了,因为 Electron、.Net Core 等框架都还未对这些系统进行适配,而且可能不在信创白名单中。