QT Installer Framework

QT Installer Framework

最近在打包公司的一款 IM 聊天软件给客户使用的时候发现 Https 请求总是失败,但是却在开发机上面运行正常,QT 依赖了 OpenSSL 的运行库来支持 Https 请求,但是我已经把 OpenSSL ToolKit 库 libcrypto-1_1-x64.dll 和 libssl-1_1-x64.dll 拷贝到了软件执行的同级目录里头,但是依然不起作用,客户那边的日志一直都是 TLS initialization failed,后面搜索 Google 查了很多文章,最后找到了答案。


1. 原因

https://bugreports.qt.io/browse/QTBUG-62637 this suggests to me, that, at least for visual studio builds, Qt no longer uses (as of 5.13) openssl for ssl, but rather windows ssl directly. Hence, copying the dlls would likely not doing anymore, except maybe for mingw builds? In either case, at the bottom, “…It’s a new feature in 5.13. You have to configure Qt properly though (it’s not enabled by default on Windows).” I really wish this was explained further, but maybe suggests why it does not work “out of the box” either. If it had, you probably would not have noticed the openssl dll’s weren’t being used. Maybe there is a better/more complete explanation of how ssl works on windows on Qt 5.13, and whether this is true for both mingw and msvc, but I did not find it offhand

上面大概说 QT 从 5.13 开始在 Windows 的运行时不再动态链接 OpenSSL 库了,单纯的拷贝过去已经不起作用了,而是直接链接 Windows SSL 库,但是你却需要正确的配置,才可以链接到 Windows SSL 运行时库,默认是不开启的,查了一圈下来,并没有发现如何配置,最后让客户安装了 OpenSSL x64 应用程序后发现可以正常请求 Https, 所以我猜测,如果安装了 OpenSSL ,他会自动复制 DLL 到 Windows 目录,并且 QT 程序在运行时也不会链接到 Windows SSL 了,而是直接链接到我们安装的 OpenSSL 里头。

使用虚拟机测试了一下,首先一台纯净的刚装上 Windows 1909 18363.1016 版本的虚拟机,直接运行我打包的程序。

已经把 OpenSSL 需要的两个 DLL 复制到了执行文件的同级目录,运行 QLDesktop.exe 登录。

这里的登录会直接向登录 API 发送 https 请求,结果发现报错了,SSL 初始化失败,原因肯定是 OpenSSL 的两个关键 DLL 并没有在运行时链接,然后安装 Win64OpenSSL-1_1_1g.exe 应用,再次运行发现 https 请求正常了,而且就算把根目录的 libcrypto-1_1-x64 和 libssl-1_1-x64 删除掉,也可以正常运行,因为 OpenSSL 在安装的时候自动把这两个 DLL 拷贝到了 C:\Windows\System32 中,https 请求在客户机上面无法工作的问题解决了,同时通过大量的 Google 浏览,发现了不少人遇到了这个问题,也同时提供了这几种解决方式:



2. 解决思路

    1. 如果自己的 QT 程序是使用 MingW 编译,那可以下载 OpenSSL 的源码,使用 MingW 编译,这样编译出来的应用程序将会使用你根目录下的 OpenSSL DLL。
    1. 将 OpenSSL 的安装程序打包到自己的软件安装中。(我们本文将采用这个方式)。
    1. 不要使用 QT 的 QNetworkRequest 发送请求,改成直接引用 OpenSSL 源码中 Lib。


3. 思路刨析

  1. 因为 Windows 下的 MingW 编译 x64 OpenSSL 问题太多,你可能会遇到无数的兼容性问题或者库问题,之前我编译 Google Protobuf 就深有体会,所以这种方式我们不采取,耗时耗力,还有可能最终没有结果。
  1. 这个方式应该是最简单,而且还可以通过 QT Installer 框架定制我们的安装过程。
  1. 最直接也是最暴力的方式,直接用 openssl 发送请求,跳过 QT 的封装,虽然也是一个非常不错的思路,但是我最终不采用的原因是因为语法过于复杂,编码过程可能不太好。


4. 认识 QT Installer Framework

Qt5 可以使用官方的 Qt Installer Framework 框架制作安装包

Qt Installer Framework 框架提供了一组工具和实用程序,用于创建一次安装程序,并在所有受支持的桌面 Qt 平台上部署它们,而无需重写源代码。安装程序将在运行它们的平台上具有本机外观:Linux,Microsoft Windows 和 OS X.

安装程序已在以下平台上进行了测试:

  • Microsoft Windows XP 及更高版本
  • Ubuntu Linux 11.10 及更高版本
  • OS X 10.7 及更高版本

使用 Qt Installer Framework 框架生成的安装程序,其中包含一组页面,可在安装,更新或卸载过程中指导用户。您需要提供安装的内容并指定有关它的信息,例如产品名称和安装程序以及许可协议的文本。

您可以通过向预定义页面添加小部件或添加整个页面来为用户提供其他选项来自定义安装程序。您可以创建脚本以向安装程序添加操作。

根据您的使用情况,您可以为最终用户提供离线在线安装程序,或两者兼而有之。



5. 下载 Qt Installer Framework

官方下载地址:

http://download.qt.io/official_releases/qt-installer-framework/

我选择的最新版本,然后我们下载 Windows 版本安装。



6. 打包应用

这一章节开始分为几个小章节介绍,有点长,请耐心观看。

6.1 windeployqt

这是打包应用的第一步,也就是先需要将自己编译的 release 版本和依赖库 都放到一起,让应用程序可以正常运行,当你的 QT 程序编码结束以后,就可以产出 release 版本了。

选择完 release 版本以后,点击菜单栏中的 build,然后在代码库下面就可以看到已经编译好的程序可执行文件了。

但是此时这个应用程序是不包含任何依赖的,如果不把依赖拷贝进来,那只能在你的开发机上面运行,别人的电脑是无法跑起来的,所以我们借助 Qt 提供的部署程序, windeployqt 来自动帮我们把依赖拷贝尽来,windeployqt 命令位于:

C:\Qt\Qt5.14.2\5.14.2\mingw73_64\bin

如果 powershell 没有找到 windeployqt 命令,请将这个路径放到系统的 path 环境变量中,然后我们 powershell 跳转到这里,运行命令:

windeployqt xxxx.exe

至此,QT 已经将我们应用程序所需要的依赖全部拷贝进来了,准备工作就算完成了。

评论