如何确定我程序需要哪些C++可再分发组件才能运行?

26

我需要安装vs2012和vs2010的vcredist吗?

我的应用程序在加载一个.dll文件时出现错误,但在我进行了一个无关的安装后突然开始工作,这让我猜测它可能安装了一个较旧的vcredist,解决了问题。不过我确定我正在使用c++11的功能。


5
使用depends - n. m.
只是告诉我缺少110.dll文件。我知道,很奇怪。但它确实是这样。 - Blub
3
如果你的程序依赖于使用另一个Visual Studio版本构建的第三方库,就可能会发生这种情况。 - Alex F
C++第三方库?嗯,我相当确定我没有使用任何其他的C++动态链接库,该产品几乎只是C#,但我意识到“几乎”并不够。我会调查一下。但总的来说,我认为2012 vcredist应该包含所有旧版本vcredist的功能。这实际上并不是真的吗? - Blub
1
我已经停止使用vs2010开发Windows一段时间了,所以我只能谈论“旧时代”。2010年的redist需要安装旧的2005 redist,因为它没有带来旧的msvc*.dll文件。也许微软已经改变了这一点,但我不这么认为,因为这会与redist的目标相抵触,即仅更新必要的操作系统部分。 - Martin Schlott
显示剩余5条评论
4个回答

16
部署是一项独立的工作。我讨厌它,我讨厌在Windows上编写安装程序……所以现在感觉好些了……
你只需要一个vcredist。链接器决定将你的程序链接到哪个版本,就用哪个版本。如果你安装了"Windows SDK",你会在其中找到实际的redist。
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\vcredist_x86

如果您安装了包括不重要的更新在内的所有更新,Microsoft 将会更新该文件夹中的 redist!
也许您有一个无法运行的可执行文件,您需要 dependency walker。这是一个非常有用的工具,以至于 Microsoft 不得不将其从 Visual Studio 中移除。下载该程序并在其中打开您的可执行文件。您不需要理解实际发生了什么。只要在打开期间没有出现对话框,一切都很好,即使底部窗口中有感叹号。如果出现类似“无法解析”的对话框,则查看下方窗口。通常,下方窗口中现在会出现像“msvcr.dll”或“msvcr100.dll”或“msvcr110.dll”之类的内容。
如果扩展名前面包含“d”,例如“msvcr100d.dll”,则表示可执行文件是在调试模式下编译的,而您的旅程将在未安装编译器的系统上结束。如果没有,那么名称将告诉您需要哪个 vcredist:

msvcr100 = VS 2010 redist (32位) (64位)

msvcr110 = VS 2012 redist (32/64位?)

有时候问题不在于msvcr,但它的名称始终以“ms”开头。当然,程序会告诉您缺失的每个dll,不仅包括微软的,还包括使用的命令。这有时非常有用。 您必须对可执行文件文件夹中的每个dll执行此操作,因为它们也可能具有无法解决的依赖项。
回到您的第一个问题。您的程序只能链接到msvcr100或msvcr110,不能同时链接两者,这就是您每个可执行文件只需要一个vcredist的原因。 如评论所述,第三方DLL可能使用不同的msvcp版本。因此,是的,您必须搜索您使用的所有DLL,并有时安装两个vcredist。

附:它们总是至少两个,msvcr和msvcp。


2
一个程序是否可以使用链接到msvcrt版本X的第三方DLL,而程序(exe)本身链接到msvcrt版本Y?在这种情况下,要启动程序,您需要两个可再发行组件。 - Martin Ba
马丁,你先说程序只能与一个链接,然后又说第三方dll可能需要两个都存在。我不清楚为什么一方面只需要一个,而另一方面两个都需要。我还安装了几个SDK在 C:\Program Files(x86)\[etc..],但有两点:首先,只有7.0A有一个Bootstrapper\packages文件夹;其次,在那里的vcredist只是vs2010 vcredist,显然不足以使用c++11功能。 - Blub
1
抱歉,让我澄清一下。如果您有一个单独的exe文件,除了系统DLL之外没有任何依赖项,那么只需要一个msvcr版本,因为链接器将该exe链接到一个版本。如果可执行文件晚绑定到不是同一编译过程的自定义DLL,则该DLL可能会链接到另一个版本的redist。在这种情况下,您必须安装两个redists。关于SDK,您是正确的。浏览我的文件夹,只有7.0A有文件夹,对此我感到抱歉。 - Martin Schlott
那么没有一个等效的文件夹,可以通过Windows更新来更新vs2012 vcredist吗?我想我知道我的问题可能是什么了。我正在使用LoadLibrary()加载jvm.dll,并找到了这篇文章:http://www.duckware.com/tech/java6msvcr71.html - Blub
那也不会对你有所帮助。例如,如果你在2010年之后安装了系统并且只安装了新的编译器和软件,msvcr71.dll仍然会缺失,因为它是2008包的一部分。更新vs2012 vcredist不包括它。为此,您必须安装那个特殊的旧版本vcredist。我没有安装2012 VS,因为我目前不在Windows平台上开始新的开发,所以我不能说是否有一个带有redist的文件夹。我认为应该有,如果在VS 2012文件夹中有一个redist,它将通过Windows更新进行更新。评论结束。 - Martin Schlott

9
如果您想知道哪些运行时是必需的,可以尝试使用github上lucasg的"Dependencies"工具(https://github.com/lucasg/Dependencies),它适用于像win10这样的现代系统。您只需要在依赖树中查找MsVcR##.dllVcRuntime###.dll(其中#表示数字)即可。
希望对您有所帮助。
注:我们多年来一直使用的老牌“dependency walker”似乎无法处理较新的操作系统如何处理延迟依赖项的方式,将其标记为“缺失”,而它们并非确实缺失,只是以一种它不知道的方式延迟加载...

8
我在Windows 7上解决了这个问题,具体如下:
  1. 我尝试加载库时失败了,显示“应用程序无法启动,因为其旁边的信息不正确。”
  2. 我打开了“计算机管理”窗口:开始->右键单击计算机->管理。
  3. 在“计算机管理”窗口中,我选择了“事件查看器” ->“Windows日志” ->“应用程序”。
  4. 与错误对应的日志说找不到某个版本的Microsoft.VC90.CRT的DLL。在我的情况下,版本是9.0.30729.6161,并通过Google搜索发现我需要安装此处的一个“非常规”的可再发行版本。
依赖项检查程序对我没有帮助(它只让我困惑,报告了不必要的依赖项)。

2
如果您的操作系统是Vista或更高版本(不是XP),请使用内置的SxStrace.exe生成加载哪些DLL以及哪个模块需要它们的日志。这将清楚地显示是否加载了多个CRT DLL版本,并且对于哪些DLL(第三方或否)。
VS2012可再发行组件位于例如“C:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC \ redist”中。
- David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接