ARTICLE · 998016
发版当天最怕的事:在我电脑上好好的,客户机就是打不开
“我这边能打开”,往往最没参考价值
Qt 项目发版最尴尬的场面,不是功能报错,而是客户双击 exe,什么都没发生。开发一脸自信地远程过去,第一句话通常还是:“奇怪,我电脑上好好的。”
我以前也被这句话坑过。开发机装着 Qt、Visual Studio,PATH 里躺着一堆 DLL,Qt Creator 启动程序时还会顺手把运行环境配好。你以为程序是独立运行,实际上它一直在“吃开发机的老本”。

Demo 更容易掩盖问题。代码少、插件少、目录简单,随手复制几个 DLL 就能启动。真实项目一上来,串口、网络、数据库、图片格式、OpenSSL、第三方 SDK 全混在一起,少一个库,有时不是弹框,而是直接秒退。
真正缺的,不一定只是一个 DLL
Qt 的 exe 只是主体,运行时还要动态加载 Qt 库、编译器运行库和插件。最典型的是平台插件:
YourApp.exe
platforms/qwindows.dll
qwindows.dll 不是随便扔在 exe 旁边就行,目录结构不对,Qt 就找不到窗口系统插件。更麻烦的是,文件明明在,版本、位数或编译器不匹配,同样打不开。
64 位程序带了 32 位 DLL,MSVC 构建混进 MinGW 库,Release 包里塞了 Debug 库,这些都属于“看着齐全,实际不能用”。

排查时我会先开插件加载日志,而不是盯着业务代码猜:
qputenv("QT_DEBUG_PLUGINS", "1");
QApplication app(argc, argv);
这么写不是为了长期保留,而是让 Qt 把“去哪里找、加载哪个库、为什么失败”吐出来。很多所谓玄学问题,到这里基本就现形了。
我后来把“干净机启动”当成发版门槛
windeployqt 可以作为起点,但不能当免责证明。我的做法是把 Release 程序放进空目录,用对应 Qt 版本的 windeployqt 收集基础依赖,再补上业务 DLL、OpenSSL、数据库驱动和厂商 SDK。

然后把整个发布包丢进一台没装 Qt、没装 Visual Studio、PATH 也很干净的虚拟机验证。
注意,是测试“最终压缩包”,不是测试开发目录。现场最常见的翻车,就是工程目录能跑,压缩时漏了子目录;或者安装脚本少拷了一个插件,开发还在拿原目录证明自己没问题。
别靠复制一堆 DLL 碰运气
有些同事遇到启动失败,会把 Qt 的 bin 目录整个复制过去。短期可能真能救火,后期却会留下版本污染、包体膨胀和许可证核对困难。
更糟的是,主界面能打开,不代表部署完整。SQL 驱动、图片插件、TLS 库,可能等到客户点某个功能时才炸。这个地方不处理,短期没事,后期基本会回来找你。
这套经验尤其适合 Windows 客户端、工业上位机、离线部署软件,以及带第三方设备 SDK 的项目。
我的判断很直接:Qt 发版不是“把 exe 发出去”,而是交付一套可复现的运行环境。开发机能跑,只能说明代码编过;干净机能跑,才说明这个版本真的能交付。