如何确定我的程序需要运行哪些 C++ 可再发行组件?
Posted
技术标签:
【中文标题】如何确定我的程序需要运行哪些 C++ 可再发行组件?【英文标题】:How do I determine which c++ redistributables my program needs to run? 【发布时间】:2013-09-03 14:36:28 【问题描述】:我是否可能需要同时为 vs2012 和 vs2010 安装 vcredist?
我刚刚遇到了一个错误,我的应用程序无法加载 .dll,并且在我进行了不相关的安装后它突然开始工作,这促使我猜测它一定安装了一个较旧的 vcredist,从而解决了这个问题。 不过我确定我使用的是 c++11 功能。
【问题讨论】:
使用depends。 depends 只告诉我缺少 110.dll。我知道,很奇怪。但确实如此。 如果您的程序依赖于使用另一个 Visual Studio 版本构建的第三方库,则可能会发生这种情况。 c++ 第三方库?嗯,我很确定我没有使用任何其他 c++ dll,该产品几乎只是 c#,但我意识到“几乎”并没有削减它。我会调查的。但总的来说,我假设 2012 vcredist 将包含旧 vcredist 的所有功能。这不是真的吗? 前段时间我停止使用 vs2010 为 Windows 进行开发。所以我只能说“旧时代”。 2010 redist 需要安装旧的 2005 redist,因为它没有带来旧的 msvc*.dll。也许 MS 改变了这一点,但我不这么认为,因为它会抵消 redist 的目标,只更新操作系统的必要部分。 【参考方案1】:部署本身就是一项工作。我讨厌它,我讨厌你必须在 Windows 上编写安装的方式。 …所以现在感觉好多了…
您只需要一个 vcredist。链接器决定将您的程序链接到的那个。如果您安装了“Windows SDK”,您将在以下位置找到实际的 redist:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\vcredist_x86
如果您安装了所有更新,包括不重要的更新,Microsoft 将在该文件夹中更新您的 redist!
也许您有一个不想运行的可执行文件,您需要dependency walker。一个工具,非常有用,以至于微软不得不从 Visual Studio 中删除它。下载程序并在其中打开您的exe。你不需要了解真正发生的事情。只要打开过程中没有出现Dialog,一切正常,即使底部窗口有感叹号。如果对话框出现“无法解决”之类的问题,请查看底部窗口。通常现在在下部窗口中有类似的东西 “msvcr.dll”或“msvcr100.dll”或“msvcr110.dll”。 如果它在“msvcr100d.dll”之类的扩展名之前包含“d”,则可执行文件在调试模式下编译,您的旅程将在没有安装编译器的系统上结束。如果没有,名称会告诉您您需要哪个 vcredist:
msvcr100 = VS 2010 redist (32bit) (64bit)
msvcr110 = VS 2012 redist (32/64bit?)
有时它不是 msvcr,但它总是以“ms”开头。当然,该程序会告诉您每个缺少的 dll,不仅是 microsoft,还告诉您使用了 dll 中的哪个命令。这有时非常有用。 您必须对可执行文件文件夹中的每个 dll 执行此操作,因为它们也可能具有无法解决的依赖关系。 回到你的第一个问题。您的程序只能链接到 msvcr100 或 msvcr110,不能同时链接到两者,这就是每个可执行文件只需要一个 vcredist 的原因。 正如评论中提到的,第三方 DLL 可能会因使用不同的 msvcp 版本而犯错。所以,是的,你必须搜索你使用的所有 DLL,并且有时你必须安装两个 vcredist。
PS:总是至少有两个,msvcr 和 msvcp。
【讨论】:
难道程序不能使用链接到版本 X 的 msvcrt 并且程序 (exe) 本身链接到版本 Y 的 msvcrt 的第 3 方 DLL 吗?在这种情况下,要启动程序,您需要两个可再发行组件。 Martin,首先你说一个程序只能链接一个,然后你说第三方 dll 可以使它有必要同时拥有两者。我不清楚如何可能一方面只需要一个,但另一方面两者都需要在那里。我还在C:\Program Files(x86)\[etc..]
中安装了几个 SDK,但有两件事:首先,只有 7.0A 甚至有一个 Bootstrapper\packages 文件夹,其次,其中的 vcredist 只是一个 vs2010 vcredist。所以这可能还不够,因为我 am 使用 c++11 功能。
对不起,让我澄清一下。如果您有一个 exe,除了系统 DLL 之外,不依赖于任何 DLL,则只需要一个 msvcr 版本,因为链接器将该 exe 链接到一个版本。如果可执行文件后期绑定了一个自定义 DLL,该 DLL 不是同一编译过程的结果,则该 DLL 可以链接到另一个版本的 redist。在这种情况下,您必须安装两个 redist。使用 SDK,您是对的。查看我的文件夹,只有 7.0A 有该文件夹,对此感到抱歉。
所以没有等效的文件夹可以通过 Windows 更新来保持 vs2012 vcredist 的更新?我想我明白了我的问题可能是什么。我通过LoadLibrary()使用jvm.dll,发现这篇文章:duckware.com/tech/java6msvcr71.html
无论如何这对你没有帮助。一个例子。如果您在 2010 年之后安装了系统并且只安装了新的编译器和软件,那么 msvcr71.dll 仍然会丢失,因为它是 2008 软件包的一部分。更新 vs2012 vcredist 不包括它。为此,您必须安装那个特殊的旧 vcredist。我还没有安装 2012 VS,因为我目前没有在 windows 基础上开始新的开发,所以我不能说是否有包含 redist 的文件夹。我假设有,如果在 VS 2012 文件夹中是一个 redist,它将由 windows update 更新。呃评论长度结束。【参考方案2】:
我解决了这个问题如下(在 Windows 7 上):
-
我尝试加载库,但未能显示“应用程序无法启动,因为它的并排信息不正确。”
我打开了“计算机管理”窗口:开始->右键单击计算机->管理。
在“计算机管理”窗口中,我选择了“事件查看器”->“Windows 日志”->“应用程序”。
错误对应的日志说没有找到某个版本的Microsoft.VC90.CRT的DLL。在我的情况下,版本是 9.0.30729.6161,在 Google 中搜索它显示我需要安装来自 here 的“不寻常”版本的可再发行组件。
dependency walker 对我没有帮助(它只是通过报告不必要的依赖关系让我感到困惑)。
【讨论】:
【参考方案3】:如果您想知道需要哪些运行时,可以尝试使用 github (https://github.com/lucasg/Dependencies) 上来自 lucasg 的“依赖项”工具,该工具适用于 win10 等现代系统。
您只需要在依赖关系树中查找MsVcR##.dll
o VcRuntime###.dll
(其中# 代表一个数字)..
HTH
PS:我们多年来一直使用的老牌“依赖步行者”似乎无法处理新操作系统处理延迟依赖的方式,将它们标记为“缺失”,虽然它们并没有缺失,只是以它不知道的方式加载延迟...
【讨论】:
【参考方案4】:如果您的操作系统是 Vista 或更高版本(不是 XP),请使用内置的 SxStrace.exe 生成正在加载哪些 DLL 以及哪些模块需要它们的日志。它会清楚地显示是否正在加载多个 CRT DLL 版本,以及用于什么 DLL(第 3 方或没有)。
VS2012 可再发行组件被放入,例如"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist"。
-- 大卫
【讨论】:
以上是关于如何确定我的程序需要运行哪些 C++ 可再发行组件?的主要内容,如果未能解决你的问题,请参考以下文章
运行没有运行时可再发行组件的 C++ 二进制文件(Server 2k3、XP SP3)