Qt 程序打包部署全攻略:从 windeployqt 到 Inno Setup 的静默安装与版本迭代实战

今天整理了一套Qt 打包部署方案,从 windeployqt 到 Inno Setup 安装,再到版本迭代的自动化,一步到位。

第一步:windeployqt

windeployqt 是 Qt 官方提供的部署工具,能自动扫描你程序依赖的 Qt 模块和插件,把需要的 DLL、资源文件一股脑拷贝到目标目录。但是他只能识别Qt 库,第三方库(比如 OpenCV、FFmpeg)需要手动处理,基础用法是在Qt命令行环境里执行:

cpp 复制代码
cd /d "你的构建目录"
windeployqt --release --no-translations --compiler-runtime YourApp.exe

--compiler-runtime:自动带上 MSVC 运行库,如果用的是MinGW,这个参数会忽略,但需要把 libgcc_s_seh-1.dll、libstdc++-6.dll 也拷走。

注意:windeployqt 只能在干净的 release 目录里跑,如果你的 exe 旁边有旧的 DLL,它可能因为版本混淆而报错。所以每次构建前,先把 deploy目录清空,再重新拷贝 exe 。

第二步:手动补全第三方 DLL 和运行时依赖

程序往往还依赖一些三方库,比如串口通信用到的 `FTD2XX.dll`,或者加密库 `libcrypto-3-x64.dll`。这些需要从编译环境或者 SDK 安装目录里找。

我用一个环境变量来管理部署目录,比如 `D:\DeployRoot\YourApp`,然后通过脚本拷贝:

cpp 复制代码
// 这不是代码,只是一个批处理片段,但 Qt 程序里我会用 QProcess 来调用它
// copy_third_party.bat
copy /Y "C:\SDK\FTDI\FTD2XX.dll" "%DEPLOY_DIR%\FTD2XX.dll"
copy /Y "D:\openssl3\lib\libcrypto-3-x64.dll" "%DEPLOY_DIR%\libcrypto-3-x64.dll"

拷贝以后最好在 Qt 程序启动时做一个静态检查,用 `QLibrary::isLibrary` 验证关键 DLL 是否存在,不存在就直接弹窗提示缺少运行库。

注意:处理调试版和发布版的差异,debug 的 DLL 通常带 `d` 后缀,比如 `Qt6Cored.dll`,打包时只拷贝 release 版本。

第三步:Inno Setup安装

文件齐全后开始制作安装包。Inno Setup 是免费神器,脚本语法简单,先写一个基础脚本 `installer.iss`:

cpp 复制代码
[Setup]
AppName=YourApp
AppVersion=1.0.0
DefaultDirName={pf}\YourCompany\YourApp
DefaultGroupName=YourApp
OutputDir=..\packages
OutputBaseFilename=Setup_YourApp_1.0.0
Compression=lzma2
SolidCompression=yes
//静默安装模式的关键参数
PrivilegesRequired=admin
UninstallDisplayIcon={app}\YourApp.exe

[Files]
//把 windeployqt 生成的整个 deploy 目录包含进来
Source: "..\deploy\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs

[Icons]
Name: "{group}\YourApp"; Filename: "{app}\YourApp.exe"
//桌面快捷方式可选,我一般不创建,免得客户嫌乱

[Run]
//安装完成后静默启动,或者不启动,看需求
Filename: "{app}\YourApp.exe"; Parameters: "--firstrun"; Flags: nowait

可以用命令行模式编译这个脚本:

复制代码
ISCC.exe installer.iss

生成 `Setup_YourApp_1.0.0.exe`,点击安装即可。

注意权限问题:、如果你的程序要写注册表或者往 Program Files 下写数据,必须强制 `PrivilegesRequired=admin`,否则 Win10 的 UAC 会弹窗拦截,静默模式直接失败。另外,安装完成后如果有驱动或服务要注册,记得在 `Run` 里用 `Flags: runhidden` 跑你的批处理,不然控制台窗口一闪而过,客户以为是 bug。

第四步:版本迭代的自动化,从 CMake 到打包

每次手动执行 windeployqt 再开 Inno Setup 过于繁琐,我们可以升级到 CI/CD 思路。我会使用 CMake 捕获版本号,生成一个 `version_info.iss` 文件,里面包含版本号和文件名。

在 CMakeLists.txt 里加一段:

复制代码
set(APP_VERSION "1.0.0")
configure_file("${CMAKE_SOURCE_DIR}/installer.iss.in" "${CMAKE_BINARY_DIR}/installer.iss" @ONLY)

然后在 `installer.iss.in` 里用 `@APP_VERSION@` 占位,比如:

复制代码
AppVersion=@APP_VERSION@
OutputBaseFilename=Setup_YourApp_@APP_VERSION@

这样每次改代码,只动一个版本号,打包脚本自动变化。还可以在 CMake 里加一个自定义 target,依次执行 windeployqt 和 ISCC,一条命令生成安装包:

复制代码
add_custom_target(package_app
    COMMAND windeployqt --release $<TARGET_FILE:YourApp>
    COMMAND ISCC.exe "${CMAKE_BINARY_DIR}/installer.iss"
    DEPENDS YourApp
)

注意:** 版本号别硬编码在 `.pro` 文件(如果你用 qmake),因为 CMake 和 qmake 混用会乱。统一用一个 `version.h` 头文件定义 `APP_VERSION_STR`,C++ 代码和 Inno Setup 都从这里读取,保证万无一失。

相关推荐
脉动数据行情15 分钟前
C# 实现德指 DAX 期货 WebSocket 实时行情监听
开发语言·websocket·c#
大圣编蚕31 分钟前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
菜鸟~noob23340 分钟前
【电子战】第02篇:能量检测器 vs. 相关检测器【含matlab代码】
开发语言·matlab
OpenAnolis小助手2 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
小玮看世界2 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
ForteScarlet2 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖2 小时前
Java深入解析篇六十二之安全机制详解
java·开发语言
老赵的博客3 小时前
c++ QT之动态库加载问题
c++·qt
菜鸟~noob2333 小时前
【电子战】 第01篇:噪声、门限与虚警/检测概率(PFA/PD)【含matlab代码】
开发语言·matlab
奇牙coding1233 小时前
GPT-6-Astra API 接入教程:OpenRouter 路由配置 + Python/curl 示例 + 静默降级踩坑
开发语言·python·gpt·ai