12. Windows端元宝功能架构实现分析

1 前言

由于通用性的知识大家都可以直接询问AI了,所以本站后续大概率不会再过多的更新过于标准化的知识点,而是会更多的更新一些经验性的东西,也就是一些软件的设计思路。

当然,我个人的经验同样也是有限的,因此本系列文章主要介绍一些大厂软件的设计经验。

本文要介绍的是元宝,它是腾讯开发的一款多端AI对话软件,支持非常多的平台:

image.png

这里主要分析Windows端元宝的技术细节与功能实现方式。

当然,我自然没有元宝的源码,因此所有的结论皆来自逆向分析,不一定准确,仅供参考。

2 版本回退设计(bug?)

我已经使用过元宝一段时间了,来到它的安装目录可以看到,它有自动后台更新功能:

image.png

并且自动更新后,并没有将老版本安装数据删除,而是将可执行文件备份了一下:

yuanbao.exe -> yuanbao.exe_back

修改文件后缀名是一种非常常见的备份策略,恢复方式自然也很简单,直接改回后缀名exe即可。

而对应的版本软件数据,直接存放在了对应版本的文件下,区分版本很方便。

2.61.11.658
2.62.0.632

但从元宝的用户界面上,我并没有找到可以回退版本的按钮。

排除bug的可能(如果是bug,那么这也太明显了……但也不能完全排除),猜测这样设计的目的,是为了当新版程序在用户电脑上因某些原因无法正常使用时,会自动回退到老版本(不排除需要用户手动回退)。

Windws的版本奇多、各类民间修改版的系统更是不甚枚举,系统因为这或那的组件缺失导致应用程序无法运行是非常正常的,而元宝的目标是最大程度的兼容用户系统,所以做出这样的设计也是可以理解的了。

唯一的缺点大概就是多占用了一倍的存储。

你可能会问,更新后,程序运行起来了,不就已经说明新版可以在系统正常运行吗?为什么此时依旧不删除老版本呢?

是的,大多数情况下,只要程序能正常启动并持续运行一段时间,基本都代表程序没什么大问题,但是……依旧有可能出现问题。

因为程序启动后并不代表所有的功能代码都会运行一遍,甚至有些代码只有当用户主动在界面上点击才可能触发,那么此时的现象就是,新版更新并持续运行一段时间都没有问题,但当用户手动触发了某个功能代码后导致了程序崩溃,而这段导致程序崩溃的代码可能就是新版更新导致的。

所以在这种情况下,依旧拥有回退的选项。

但在元宝的用户界面上,我并没有看到可以暂停自动更新的选项……

不过经过测试,如果是我主动更新、点击重启更新,那么上一个老版本的数据还是会被自动清理的。

3 更新功能设计

手动更新版本后,程序文件结构就清新多了:

image.png

  • 2.62.0.632:版本号作为文件夹名称,其内存放该版本的所有数据、可执行文件。
  • UpdateSvr:用于更新元宝版本的程序。
  • yuanbao.exe:入口执行文件。

其中UpdateSvr后面的Sv,一般指的就是服务(service),可以直接来到Windows系统服务功能,找到元宝注册的这个系统服务:

image.png

比较良心的是没有设置成自动触发,目前默认设置的是手动(可以等同于启动元宝后,由元宝自己去触发更新程序升级版本了):

image.png

可以看到这个服务的可执行文件路径,实际上就是上面元宝的UpdateSvr目录下的可执行文件。

不像WPS,直接设置了一个定时器,只要你登录进系统,就会默认执行一次更新,并且每隔一小时就会自动执行一次,多少有点流氓了:

image.png

更新版本之所以需要专门写一个程序,主要还是Windows系统的问题,因为Windows系统不允许修改正常运行的程序,也就是当元宝正在运行时,是不允许修改自身的,只能借助另外的程序。

你或许时常会遇到在Windows系统上删除文件发现删除不掉,报错是该文件被某某某占用、或正在运行中,与这里就属于类似的问题。

而系统服务的好处就在于它可以脱离程序本身,比如,如果这里的更新服务设置为自动,那么无论你启没启动元宝,只要你启动了Windows系统,这个更新服务都会自动运行、完成版本的更新。

因此这算是一种程序版本更新的标准化设计了。

4 兼容性设计

元宝为了提高程序的系统兼容性是下了功夫的。

当然,也可能是腾讯内部的开发规范就向来如此,默认直接将所有依赖的系统调用都直接打包进程序包里了:

image.png

类似于api-ms-win-core-*这类动态库,基本都是Windows系统自带的底层核心库,里面包含了多数通用的win api,比如文件读写api等等。

我们可以使用vs自带的dumpbin工具查看这些dll文件的导出函数,比如最基本的CreateFile函数就在这个dll中:

image.png

一般来说,绝大多数人的系统,都不太可能会缺少这种核心库,但为了尽最大可能降低因用户系统导致的兼容性问题,所以采用了这种非常极端的方案。

这样的好处是显而易见的,这能够尽最大的可能性保证所有用户使用的元宝都在一个基本完全相同的环境下运行,如果出现了问题是非常方便排查的,否则很多时候,就只能一个个去联系用户去复现、非常的耗时耗力。

5 资源解析

元宝这里用了三个文件夹存放三种不同类型的文件,也是很规范的用法了:

image.png

其中assets与一般规范一致,存放的是一些预处理资源,比如这个文件夹里面目前存放的是icon图片。

locales文件夹里面存放的是不同语言的翻译文件,比如中文的“你好”,在英文下就是“hello”。

yuanbao.ftl

里面存放的是国家化(i18n)资源文件,.ftl后缀文件一般指的是Fluent 语言文件格式,一个典型示例如下。

英文版本:

hello = Hello
welcome-user = Welcome, { $name }!

中文版本:

hello = 你好  
welcome-user = 欢迎你,{ $name }!

要解析这个资源文件比较简单,只需要初始化一个node项目。添加一下包:

npm install @fluent/bundle 

然后运行一下代码就行了:

import { FluentBundle, FluentResource } from "@fluent/bundle";
import fs from "fs";
// 读取 ftl 文件
const ftlText = fs.readFileSync("yuanbao.ftl", "utf-8");
// 解析资源
const resource = new FluentResource(ftlText);
resource.body.forEach(item => {
  console.log(item);
});

效果如下:

image.png

对应的香港语言包解析结果:

image.png

最后的raw文件夹就很纯粹了,就是一些原始文件,比如这里放的是一些音频文件:

image.png

6 功能模块分析

一般来说,现代多数程序都会依赖开源项目,而很多开源项目都会只提供dll版本的库以供使用,目的很简单,可以提高知名度,因为只要你用了这个项目,你的程序安装目录里面就会有它的动态库名称。

包括现代项目多数都是团队协作完成的,不太可能将所有人开发的所有功能都放在一个项目内,一般会提供类型子项目、插件的形式,比如dll,让其它人开发的功能独立为一个模块,不影响主程序逻辑、只需要在加载的时候加载一下dll即可。

因此要看判断一个程序有哪些功能、以及实现逻辑,最简单的方式就是直接看它依赖了哪些动态库或其它程序。

比如其安装目录中最明显的一个就是崩溃处理程序:

  • YuanbaoCrashHandler.exe
  • CrashpadHandlerExtension.exe

很明显,这两个程序就是专门用于处理元宝崩溃的,可能会在检测到元宝崩溃后,上传崩溃时的日志、环境信息等等,以方便分析崩溃的原因。

用于实现AAC标准的音频编码/解码库:

  • fdk-aac.dll

对应的开源项目源码:https://github.com/mstorsjo/fdk-aac

用于即时聊天通信的、腾讯自家的、但不再一个业务线,属于腾讯云服务的开源组件:

  • ImSDK.dll

对应的开源项目源码:https://github.com/TencentCloud/TIMSDK

用于不同格式的视频编码/解码库:

  • libr264.dll
  • libr265decoder.dll
  • libt265.dll

有类似名称的开源项目,但名称不完全一致,可能被腾讯魔改过、也可能是其内部研发的功能组件,但从264、256这类名称可以猜测,其大概率是用于视频格式编码解码的,因为有两种视频格式的名称分别为:h.264、h.265。

  • H.264:自2003年推出,广泛应用于直播、监控、视频会议等场景,兼容性强,适合老旧设备和低功耗场景。它在相同画质下,文件体积通常较大,适合存储和播放。
  • H.265:自2013年推出,旨在以更小的体积保持同等画质,压缩效率提升约40%~50%。它适用于4K和8K超高清视频,适合需要高分辨率和高帧率的场景。

高性能用户态的网络数据包处理引擎:

  • libvppfilter.dll

可能来源于开源项目:https://github.com/FDio/vpp

腾讯开源的轻量、高性能、用rust开发的QUIC协议库:

  • tquic.dll

来源于开源项目:https://github.com/tencent/tquic

腾讯开源的、来源于腾讯微信产品线的跨平台数据库框架:

  • WCDB.dll

来源于开源项目:https://github.com/Tencent/wcdb

腾讯内部的、属于腾讯会议业务线的功能组件,并没有开源出来:

  • xcast.dll
  • wemeet_base.dll

甚至还有相关的配置文件:xcast.conf

image.png

可以看到都是一些与音视频相关的配置。

从上面这些功能模块就能大致看出来元宝未来的发展方向,并不会止步于一个简单的AI聊天软件,包括已经集成进的OpenClaw可以实现AI对电脑的控制,上方大量与音视频相关的模块可以看到其未来也会向着音视频方向发展,比如最直接的点就是AI生成音频、视频,以及可能的元宝派实现多人聊天之类的。

7 UI分析

允许元宝后,从进程管理器中就能直接看到,元宝采用的是Windows自带的webview实现的UI显示:

image.png

这是一个浏览器技术,不像Electron框架,每个应用打包之后都内嵌了一个浏览器,Webview2是在系统上预安装了的组件,其它程序只需要按其接口开发、无需打包浏览器就能发给用户使用,这使得软件打包后的体积会更小。

不同语言基本都有对应的库可以直接对接,比如rust中就有一个tauri框架在Windows平台上就是基于Webview2实现的。

通过Exeinfo PE工具可以查看它的编译信息:

image.png

问问AI就可以大致判断它是用C++写的,用vs2022编译的:

image.png

不得不说,腾讯技术实力还是很强劲的,基本各类程序都是优先使用C/C++,性能极佳、体积极小,不像目前很多程序动不动就是Electron,随便写点东西打包一下就是几百兆。

C++版本webview跨平台开源SDK库:https://github.com/webview/webview

虽说腾讯也不一定用的是这个、内部自己实现的也不一定。

至于UI美学方案这里就不探讨了,毕竟没有这方面的经验,但就从用户简单来说,元宝的UI做的是真顺滑、非常流畅、好看。

8 总结

最后再总结一下元宝的整体设计规范与正在使用的相关技术细节,如果你正在做相关的PC端程序、涉及到相关的功能,或许可以参考腾讯大厂的实现方案,说不定可以少走许多弯路:

  1. 直接用版本号作为该版本软件所有数据的目录名。
  2. 使用系统服务程序完成软件自动更新。
  3. 打包所有必要的动态库,尽最大可能提高程序的兼容性。
  4. 用FLT(Fluent Translation List)语言格式实现多语言管理。
  5. 音频编码/解码可以使用:fdk-aac
  6. 即时聊天通信可以使用:TimSDK
  7. 需要提高网络数据包处理性能可以使用:vpp
  8. 用QUIC协议可以使用:tquic
  9. 跨平台数据库框架可以使用:wcdb
  10. C++ UI开发可以使用:webview2
作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux