【问题标题】:Should I redistribute msvcrt.dll with my application?我应该用我的应用程序重新分发 msvcrt.dll 吗?
【发布时间】:2010-11-07 14:15:04
【问题描述】:

如果应用程序的某些库动态依赖于 msvcrt.dll,我是否应该在我的应用程序中重新分发 msvcrt.dll 并使用私有 dll? IE。系统的 msvcrt.dll(dll 地狱)是否可能存在任何不兼容问题?应用程序面向 Windows Server 系统。

【问题讨论】:

  • 我不会结束投票,因为现有的答案很重要,但读者应该注意这个问题没有明确说明。在实践中,您应该做什么取决于您使用的编译器,例如,对于 MinGW,您没有实际的选择,只能假设 msvcrt.dll 将仍然是 Windows 的一部分。

标签: windows deployment dll msvcrt


【解决方案1】:

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

在 Windows 中使用 C 运行时有两种选择:

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

  2. 链接到动态 C 运行时库。
    您将对 cl.exe 使用 /MD 或 /MDd 选项。
    在 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 的要求。在Windoes 2000 之前,开发人员甚至会在\Windows 安装文件夹中安装一个新的MSVCRT.dll。但是,在许多应用程序和操作系统之间共享 CRT,结果证明是一个非常糟糕的主意。在 WinXP SP2 中,Windows 附带的 CRT 发生了显着变化,任何依赖于该 CRT 版本的应用程序都有被破坏的风险。

此时,Microsoft 告诉开发人员,Windows 中包含的 MSVCRT.dll 是操作系统的一部分,可以随时提供服务或修补。不支持针对它构建应用程序。因此应用程序应使用上述方法之一。

参考资料:

【讨论】:

    【解决方案2】:

    您必须在您的应用程序中提供 msvcrt。它不是操作系统的保证部分。如果某个特定版本的 Windows碰巧拥有它,那只是因为 Windows 中的某些东西正在使用它。

    当较新版本的 Windows 没有发生包含人们认为 Windows 附带的二进制文件时,应用程序已经崩溃。当用户选择不安装 WinFax 时,应用程序已经崩溃,这意味着没有安装 msvcrt。

    来自Raymond Chen:

    取决于 Windows 的版本 你在跑步,可能有各种各样 的支持 DLL 的东西不是 正式的产品组件,但其中 只是为了搭便车。

    ...

    这个问题今天仍然存在。人们去 搜索二进制文件 自带 Windows 寻找 他们可以remora。然后 当这些二进制文件时,他们感到惊讶 完全改变或消失。

    来自KB326922 - Redistribution of the shared C runtime component in Visual C++:

    ...不再考虑 CRT DLL 因此,系统文件分发 CRT DLL 与任何应用程序 依赖它。因为它不再 一个系统组件,将其安装在您的 应用程序文件目录 与其他特定于应用程序的代码。 这可以防止您的应用程序 使用其他版本的 CRT 可能安装在 系统路径。

    如果您链接到 MSVCRT,您必须将 msvcrt 与您的应用程序一起提供。

    更多

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

    虽然MSVCRT.DLL是操作系统DLL很久了,and has been documented as off-limits to applications,还有a lot of people谁treat it as a C runtime delivery channel,这些程序给产品团队制造了很多悲痛。

    您必须随您的应用程序重新分发 Microsoft Visual C 运行时,因为 Windows 不附带任何 Microsoft Visual C 运行时。可能发生有一个名为 msvcrt.dll 的 DLL(不能保证),它不是 MSVCRT。

    【讨论】:

    • 是的,确实如此。 Windows SDK 没有表明 Windows XP/Vista/Seven 将 MSVCRT 作为可以使用的二进制文件提供。 Windows 可能附带某些版本的 MSVCRT,但几乎可以肯定它不是您所依赖的 MSVCRT 的确切版本。而且 Windows 更新不会为您的客户提供更新版本的运行时。微软开发人员 Raymond Chen 的博客拥有大量追随者,他在那里谈论人们做错的事情。这是正确的答案,无论反对者是否想听到它。
    • 这是不正确的。至少 10 年来,msvcrt.dll 一直是系统 DLL。
    • @DavidHeffernan 因此it is not guaranteed to be there。 (“表示它是Windows拥有和构建的系统组件。它仅供系统级组件将来使用。”) 如果你想使用它,你需要发布它。如果您认为它存在并且永远存在于用户的机器上:您做错了。
    • @HarryJohnston 人们不应将 MSVCRT 与 msvcrt.dll 混淆。如果您的应用程序依赖于 MSVCRT,那么您需要重新分发您构建时使用的适当版本的 Microsoft Visual C++ 运行时 - 这永远不会是 msvcrt.dll(因为这是一个您永远无法使用的私有 dll链接)
    • @IanBoyd:实际上 MinGW 应用程序默认链接到 msvcrt.dll - 他们不应该,但他们这样做。我担心的是,当您说 msvcrt 时,人们会认为您在谈论 msvcrt.dll。也许你可以拼出来 - “Microsoft C runtime”而不是“msvcrt”?并澄清您不得发送msvcrt.dll,即使这是您所链接的对象?
    【解决方案3】:

    克里斯的回答不应该被否决,因为两者都是正确的。

    问题在于有两组不同的 MSVCRT。一套是Visual Studio自带的msvcrt80.dll、msvcrt90.dll等。这是人们通常使用的。正如其他答案所述,它们必须重新分配。

    另一个是 System32 文件夹中的 msvcrt.dll(文件名中没有数字),从前一段时间以来,它仅供操作系统本身使用。并且应用程序永远不应该替换/重新安装它。但是,某些应用程序确实链接到它,出于某些原因,例如删除要安装的额外依赖项。但请注意,它不保证在未来的 Windows 版本中可用。

    【讨论】:

    • 您永远不应该依赖 system32 中的 msvcrt.dll。它是 Windows 的一部分,没有记录或可能经过测试以供一般使用。有一天它可能会消失,或者你需要的功能可能会作为安全更新的一部分而改变,你的应用就会被破坏。
    • @Stewart:我认为不太可能发生不兼容的函数更改,因为它会破坏使用 Visual Studio 6 构建的任何应用程序。它可能会消失,但前提是安装随 VS6 分发的版本可以工作(这似乎值得怀疑)。
    • VC6 自带的 msvcrt.dll(来了?)与 windows 自带的不一样。它恰好具有相同的名称,但 windows 附带的名称是 windows 的未记录部分,而不是 VC6 的 CRT。你永远不应该使用它。当然,您也不应该使用 VC6 附带的 msvcrt.dll,因为它已经失去支持多年,并且还没有修复所有安全漏洞。 VC6 现在已经快 15 岁了——你真的应该停止使用它。
    • @Stewart:使用 Visual Studio 6 构建的应用程序在现代版本的 Windows 上运行时,使用内置的 msvcrt.dll。微软致力于向后兼容,破坏现有的 Visual Studio 6 应用程序不是他们的选择。我不推荐使用 msvcrt.dll(真的希望 MinGW 在默认情况下不这样做),但实际上,至少 32 位版本不太可能消失。
    【解决方案4】:

    msvcrt.dll 已成为操作系统分发的事实上的一部分。在 Windows 98 和 95 以及可能的 NT4 上,如果有人愿意从安装中删除诸如写字板之类的应用程序,则可以在没有它的情况下安装操作系统。

    然而,鉴于其无处不在,而且自从那些操作系统以来,很少有应用程序开发人员费心发布它,至少从 Windows 2000 开始,它就成为了操作系统的官方部分。

    Microsoft 支持有一个tool,您可以使用它来仔细检查 DLL 随附的产品。

    执行this 之类的搜索,您可以看到 msvcrt.dll vsrsion 7.0.3790.0 是 Windows Server 2003 版本的一部分。

    【讨论】:

    • 微软已经直截了当地表示 (support.microsoft.com/kb/326922) msvcrt 不再是一个系统组件。
    • 除了他们已经将它包含在自 95 以来的每个版本的 windows 中,甚至今天 notepad.exe 在 windows 7 中仍然依赖它。
    • @IanBoyd:当我读到它时,那篇文章只谈论 msvcrtnn.dll,而不是普通的旧 msvcrt.dll。
    • @rogerdpack:这是偶然的,不值得依赖,就像MFC 甚至.Net。
    • Windows 95 的第一个零售版本(4.00.950 不带“a”、“B”或“C”)没有此文件。
    猜你喜欢
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多