使用 msvc 2015 编译的 Windows 桌面应用程序的便携式安装
Posted
技术标签:
【中文标题】使用 msvc 2015 编译的 Windows 桌面应用程序的便携式安装【英文标题】:Portable installation for windows desktop app compiled with msvc 2015 【发布时间】:2017-03-23 08:07:03 【问题描述】:最近我为我的 Qt 应用程序从 mingw 切换到 msvc 编译器。
我正在使用 Qt5.8。 msvc 调试器来自 windows 10 工具包(尽管我在 Win7 和 Win8.1 上开发)和来自 vc++2015 构建工具的编译器。
我可以在本地运行该应用程序,但我无法在另一台干净的计算机上运行它。
我知道我必须将编译器特定的 dll 复制到应用程序的可执行目录中。所有其他 dll 都由 windeployqt
找到。我仍然没有让它工作。由于需要能够从 pendrive 加载应用程序,我无法发送用户必须安装的 vc_redist 软件包。在开发机器上有几个同名的dll,我怎样才能确定编译的应用程序实际使用了哪些?
有问题的 dll 尤其是 api-ms-win-crt-runtime-l1-1-0.dll
。
在部署时我遇到了这些错误:
我还尝试了 Dependency Walker 并显示了完整路径。我认为第一个层次结构级别是重要的,这就是我隐藏更深层次结构的原因。我想知道为什么完整路径显示目录System32
,因为这不是64位文件夹吗?我没有针对任何特定的,但我的应用程序必须在 x86 上运行。这是误会吗?
编辑
根据another question 和这个Microsoft blog update,当我另外包含此文件夹C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86
中的所有dll 时,它对我有用。还有一个名为 ucrtbase.dll 的文件。我不知道为什么 DependencyWalker 显示不同的。
【问题讨论】:
how can I figure out which ones are actually used by the compiled app?
您可以使用Dependency Walker 找出答案,但奇怪的是windeployqt
没有将这些与所有其他dll 一起放置。
我应该补充说我尝试了 Dependency Walker。我将添加一个图像。谢谢
@Dmitry windeployqt
不要将 msvc DLL 与其他 DLL 一起使用,因为推荐的部署方法是 MSVC 运行时应安装在最终用户计算机上。因此,windeployqt
将您应该安装的 vc_redist
安装程序作为您自己的安装程序的一部分。
@BenjaminT,谢谢,很高兴知道。
使用windeployqt
后文件夹中几乎没有vc_redist文件。使用 windeployqt 时,我只收到警告 Cannot find Visual Studio release redistributable files in C:\Program files(x86)\Microsoft Visual Studio 14.0\VC\redist
【参考方案1】:
您可以使用Dependency Walker 等工具来查看任何其他DLL 或exe 文件使用了哪个DLL。 编辑:你也可以看看 MSDN 上的Determining Which DLLs to Redistribute
您还可以使用静态链接来链接 MSVC 运行时(即使用 /MT
开关而不是 /MD
(请参阅 https://msdn.microsoft.com/en-US/library/2kzt1wy3.aspx)。但这也意味着重建 Qt,但它也会给你机会构建 Qt 的静态版本,这意味着您不需要将任何 DLL 与您的 exe 一起发布。您可以在 Qt wiki 上找到更多信息:Build Standalone Qt Application for Windows
【讨论】:
由于许可,静态链接不是一个选项。 @user2366975 许可是静态链接 Qt 的问题,您仍然可以构建动态 Qt 与 MSVC 的静态链接。 听起来很有趣。我还需要为这种情况重建 Qt 吗? @user2366975 是的,因为分布式 Qt dll 也需要 msvc dll。所以你需要构建自己的 Qt dll 并静态链接到 msvc。 在this 4 岁的线程中,我读到了Quick answer is: you can't compile Qt with MSVC statically compiled into Qt libs. it is because memory allocation for objects is done in different places in Qt(like in QtGUI, QtCore etc...) and this objects then shred between this libraries. MT compiles each DLL with own runtime/memory allocation procedure, you can't allocate memory in one DLL and destroy it in another...
以上是关于使用 msvc 2015 编译的 Windows 桌面应用程序的便携式安装的主要内容,如果未能解决你的问题,请参考以下文章
使用 MSVC2015 在 Windows 上进行 clang-tidy
g++ , msvc 2015,2017System: Windows
gTest在Windows10环境下通过VS2015的使用方法