我应该在我的应用程序中重新分发msvcrt.dll吗?

34

我应该将msvcrt.dll与我的应用程序一起重新分发,并在某些应用程序的库动态依赖于msvcrt.dll时使用私有dll吗?也就是说,系统的msvcrt.dll是否可能存在任何不兼容问题(dll hell)?应用程序的目标是Windows Server系统。


1
我不会关闭投票,因为现有的答案很重要,但读者应该注意到这个问题是未明确说明的。实际上,你应该做什么取决于你使用的编译器,例如,使用MinGW,你没有现实选项,只能假设msvcrt.dll将继续作为Windows的一部分存在。 - Harry Johnston
4个回答

33

msvcrt是用于Microsoft Visual C++运行时的动态库。

在Windows中,有两种使用C运行时的选项:

  1. 链接静态运行时库。
    使用/MT/MTd选项来调用cl.exe。在这种情况下,您不会依赖于msvcrt DLL,因此您无需重新分发它。在Visual Studio中,右键单击项目或解决方案,属性> C/C++>代码生成>运行时库使用多线程多线程调试。这是更简单的方法。缺点是生成的可执行文件较大。

  2. 链接动态C运行时库。
    您将使用/MD/MDd选项来调用cl.exe。
    在Visual Studio中,右键单击项目或解决方案,属性> C/C++>代码生成>运行时库使用多线程动态链接多线程动态链接调试。这会导致较小的EXE,但缺点是必须在安装应用程序时安装所需的MSVCRT。


每个VC++编译器版本都附带一个C运行库(CRT)版本。Visual Studio 2005附带了v8编译器和v8 CRT。实际的v8 DLL是msvcrt80.dll。对于VS2008,它是v9,动态CRT是msvcrt90.dll。但是,CRT比C/C++编译器更频繁地更新和修补。开发人员可以下载更新的CRT,并构建相应版本。如果使用动态CRT库进行编译,则必须从microsoft.com下载必要版本的运行时可再分发包,并在应用程序安装期间执行(可能是静默)安装。
在VS2005之前,开发人员构建的应用程序依赖于Windows操作系统中的MSVCRT。这将提供DLL的好处(小图像大小),同时不需要在应用程序安装中运输CRT DLL。在Windows 2000之前,开发人员甚至会在\ Windows安装文件夹中安装新的MSVCRT.dll。但是,跨许多应用程序和操作系统共享CRT也被证明是一个非常糟糕的想法。随着WinXP SP2,Windows附带的CRT发生了重大变化,任何依赖于该版本CRT的应用程序都面临着风险。
此时,微软告诉开发人员,包含在Windows中的MSVCRT.dll是操作系统的一部分,可以在任何时候进行服务或修补。不支持针对它构建应用程序。因此,应用程序应使用上述方法之一。
参考资料:

26
必须将msvcrt与应用程序一起发布。它不是操作系统的必备部分。如果某个版本的Windows 恰好具有它,那只是因为Windows中的某些内容正在使用它。
当新版本的Windows没有人们假定Windows所带二进制文件时,应用程序会崩溃。当用户选择不安装WinFax时,应用程序也会崩溃,这意味着未安装msvcrt。
来自Raymond Chen

根据您运行的Windows版本,可能会有各种支持DLL,用于处理非正式产品组件,但仅是随行而至。

...

这个问题今天仍然存在。人们在Windows附带的二进制文件中四处搜寻他们可以remora的东西。然后当这些二进制文件发生变化或完全消失时,他们会感到惊讶。

来自KB326922 - Visual C++中共享C运行时组件的重新分配
"你需要将CRT DLL与任何依赖它的应用程序一起分发,因为CRT DLL不再被视为系统文件。由于它不再是系统组件,请将其安装在应用程序Program Files目录中以及其他应用程序特定代码。这可以防止您的应用程序使用可能安装在系统路径上的CRT库的其他版本。如果您链接到MSVCRT,则必须随应用程序一起发布msvcrt。

更多信息:

决定只是放弃并将其声明为操作系统DLL,仅供操作系统组件使用。

尽管MSVCRT.DLL长期以来一直是操作系统DLL,并已记录为禁止应用程序使用,但仍有很多人将其视为C运行时交付通道,这些程序为产品团队带来了很多麻烦。和已记录为禁止应用程序使用 很多人 将其视为C运行时交付通道。"

你需要在应用程序中重新分发 Microsoft Visual C 运行时,因为 Windows 没有提供任何 Microsoft Visual C 运行时。可能会出现一个名为“msvcrt.dll”的 DLL(不保证),但它不是 MSVCRT。请注意,这段话中的标签都要保留。

3
是的,确实如此。Windows SDK没有在任何地方指出Windows XP/Vista/Seven提供MSVCRT作为可用的二进制文件。Windows可能会带有某个版本的MSVCRT,但它几乎肯定不是你所依赖的确切版本。而且Windows更新也不会为你的客户提供更新的运行时库。微软开发者雷蒙德·陈(Raymond Chen)的博客拥有大量追随者,他在博客中谈论人们的错误做法。这是正确的答案,无论反对者是否想听。 - Ian Boyd
3
这是不正确的。至少在过去的10年中,msvcrt.dll一直是系统DLL。 - David Heffernan
2
@DavidHeffernan 因此,它不保证存在(http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx)。*(“这意味着它是由Windows拥有和构建的系统组件。它仅供系统级组件将来使用。”)*如果您想使用它,您需要将其打包。如果您假设它存在于用户的计算机上,并且永远存在:那么您就错了。 - Ian Boyd
2
@HarryJohnston 人们不应该将 MSVCRT 和 msvcrt.dll 混淆。如果您的应用程序依赖于 MSVCRT,则需要重新分发与您所建立的 Microsoft Visual C++ 运行时库相对应的版本 - 它永远不会是 msvcrt.dll(因为那是一个私有 dll,您永远无法链接)。 - Ian Boyd
1
@IanBoyd:实际上,MinGW应用程序默认链接到msvcrt.dll - 它们不应该,但它们确实这样做。我的担忧是人们会认为你说的是msvcrt.dll,当你说msvcrt时。也许你可以把它写清楚 - 用“Microsoft C runtime”代替“msvcrt”?并澄清即使你链接到它,也不能发布msvcrt.dll - Harry Johnston
显示剩余7条评论

13

Chris的回答不应该被投票否定,因为两种方法都是正确的。

问题在于有两套不同的MSVCRTs。一套是msvcrt80.dll, msvcrt90.dll等与Visual Studio一起提供的,这是人们通常使用的。并且它们必须要被重新分发,就像其他答案中所说的那样。

另一套是System32文件夹中的msvcrt.dll(文件名中没有数字),旨在仅由操作系统自身使用。应用程序不应该替换/重新安装它。但是,一些应用程序确实会链接到它,出于某些原因,例如删除额外的依赖项以进行安装。但请注意,在未来的Windows版本中不能保证其可用性。


6
你不应该依赖于系统32中的msvcrt.dll。它是Windows的一部分,没有文件说明,并且可能未经过通用使用的测试。有一天,它可能会消失,或者你需要的函数可能会因为安全更新而改变,导致你的应用程序崩溃。 - Stewart
@Stewart:我认为不太可能出现不兼容的函数更改,因为这将破坏使用Visual Studio 6构建的任何应用程序。它可能会消失,但只有在安装与VS6分发的版本可以正常工作的情况下才可能发生(这似乎不太可能)。 - Harry Johnston
4
VC6附带的msvcrt.dll与Windows自带的不同,虽然名字相同,但是Windows自带的是Windows的未记录的一部分,而不是VC6的CRT。你不应该使用它。当然,你也不应该使用VC6附带的msvcrt.dll,因为它已经停止支持多年,并且没有修复所有的安全漏洞。VC6现在已经快15年了 - 你真的应该停止使用它。 - Stewart
@Stewart:使用Visual Studio 6构建的应用程序在现代版本的Windows上运行时,会使用内置的msvcrt.dll。微软致力于向后兼容,破坏现有的Visual Studio 6应用程序对他们来说不是一个选项。我不建议使用msvcrt.dll(并且真的希望MinGW默认情况下不要这样做),但实际上至少32位版本不太可能消失。 - Harry Johnston

5

msvcrt.dll已成为操作系统分发的事实标准。在Windows 98和95以及可能的NT4上,如果去除WordPad等应用程序,则可以获得不含有它的OS安装。

然而,由于其普及性,自那些操作系统以来很少有应用程序开发人员费心去安装它,至少自Windows 2000以来,它已成为操作系统的官方组成部分。

Microsoft支持有一个工具,您可以使用它来双重检查DLL与哪些产品一起提供。

执行类似这样的搜索,您可以看到msvcrt.dll版本7.0.3790.0是Windows Server 2003发布的一部分。


3
微软明确表示(http://support.microsoft.com/kb/326922),msvcrt不再是系统组件。 - Ian Boyd
除此之外,自Windows 95以来,他们在每个版本的Windows中都包含了它,即使在Windows 7中,notepad.exe仍然依赖它。 - rogerdpack
2
@IanBoyd:据我所读,那篇文章只是在谈论msvcrtnn.dll,而不是普通的msvcrt.dll。 - Harry Johnston
2
@rogerdpack:这只是附带的,不能依赖它,就像MFC或者甚至.Net一样。 - nerraga
Windows 95的第一个零售版本(4.00.950,没有'a'、'B'或'C')没有这个文件。 - kolen

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