对用户模式驱动程序和桌面应用使用 Microsoft C 运行时

本主题提供有关与适用于 Windows 8 和 Windows 8.1 的应用程序和驱动程序一起分发 C 运行时库的信息。它提供用于用户模式驱动程序和桌面应用程序写入程序的指南,使你能够编辑代码并进行打包,以用于与必需的 C 运行时库一起再分发。

  • C 运行时库 (CRT) 不再作为 Windows 共享组件附带
  • 为什么 Microsoft 做出此更改?
  • 使用 C 运行时构建代码
  • 再分发 C 运行时
  • 建议的策略
  • 将代码与 C 运行时库相链接
  • 总结 - 你需要做的事项
  • 相关主题

C 运行时库 (CRT) 不再作为 Windows 共享组件附带

过去,Microsoft 将 C 运行时库 (CRT) 作为 Window 共享系统组件进行分发。在以前版本的 WDK 中,当你构建驱动程序或传统 Windows 应用时,可以将代码与 CRT 的 Windows 系统版本相链接。随着 Windows 8 的发布,C 运行时库不再被当作系统组件,而且你必须在用户模式驱动程序或桌面应用程序中附带可再分发的 CRT 版本。本主题讨论此更改的原因、C 运行时的新组件,以及用于构建桌面应用或驱动程序并再分发 CRT 的策略。

为什么 Microsoft 做出此更改?

现在有两个单独的 C 运行时版本。一个是内部 Windows 组件,另一个由应用程序和驱动程序开发人员使用,并随 Visual Studio 附带。此更改的主要原因是为了保持一致性并支持对客户的 CRT 服务。

在过去,应用程序有时链接到未安装正确 CRT DLL 版本的计算机上的 CRT 版本。使用 CRT 的通用公共版本将有助于消除此问题。

此外,为 CRT 提供服务可能很复杂。Visual C 团队计划在 Visual Studio 中附带 CRT 的定期更新。通过使用建议的再分发策略,你可以轻松为你的应用程序拾取这些更改。而且,你不必担心 Windows 系统版本的 CRT 中的更改会打断你的应用程序。

现在,msvcrt.dll 是一个由 Windows 拥有和构建的系统组件。它仅适用于由系统级组件使用。文件 msvcr110.dll (Visual Studio 2012) 或 msvcr120.dll (Microsoft Visual Studio 2013) 是 CRT 的新公共版本,可供桌面应用程序和用户模式驱动程序开发人员使用。

使用 C 运行时构建代码

Visual C++ 在开发系统上的 System32 目录中安装最新版本的 CRT。这是出于为开发人员提供便利而安装的。否则,使用与共享 CRT 链接的 Visual C++ 构建的所有项目都需要在构建目录中存在 DLL 的副本,以用于调试和执行。msvcr120.dll 可以用于针对 Windows 8.1、Windows 8 和以前版本的 Windows(从 Windows Vista 开始)的驱动程序。

再分发 C 运行时

当你在 Microsoft Visual Studio 中构建用户模式的驱动程序或传统桌面应用程序,并且该应用程序使用 C 运行时库 (CRT) 时,你必须分发适当的 CRT 动态链接库。

用于再分发 CRT 的建议策略取决于你构建的应用程序或驱动程序类型。对于 Windows 8 和 Windows 8.1,Microsoft 提供 Visual C++ Redistributable Package(VCRedist_x86.exe、VCRedist_x64.exe 和 VCRedist_arm.exe),它包含在 Visual Studio 中。开发人员可以将可再分发的包与其他二进制文件链接。 如果你使用可再分发的包,可以在客户的计算机上自动为 C/C++ 运行时提供服务。 如果你想要实现分离,可以静态链接,或将特定的 Visual C/C++ DLL 与其他二进制文件一起复制到应用程序本地文件夹中。应用程序本地文件夹是包含可执行应用程序文件的文件夹。DLL 必须部署到应用程序本地文件夹中。

将 Visual C/C++ Redistributable Package (VCRedist_*.exe) 作为应用程序为其提供服务。如果你的安装包含可再分发的包,则在初始安装时作为完整包安装在 System32 中,并使用 Microsoft 更新服务。Visual C/C++ Redistributable Package 的所有组件都作为单个单位进行更新。

如果你将单个 CRT 组件复制到 System32 而不使用可再分发的包,则不会自动为其提供服务,而且可能会被意外覆盖。

如果驱动程序将 CRT 组件复制到 System32,而且另一个程序运行可再分发的包,这将存在潜在问题,由驱动程序安装的版本将被覆盖。相反的情况也会存在潜在问题。如果程序运行可再分发的包,并且驱动程序将较早版本的 CRT 组件复制到 System32,则可能打断应用程序。INF 安装过程只是针对已存在于 System32 中的库来检查要安装的库的版本号,如果不同则覆盖它。

建议的策略

当与你的驱动程序和应用程序一起再分发 C/C++ 运行时,请使用以下策略。

对于在“程序文件”下安装的应用程序:

  • 使用 Visual C++ Redistributable Package(VCRedist_x86.exe、VCRedist_x64.exe 和 VCRedist_arm.exe),它可在 System32 下部署 CRT。在此情况下,可以自动更新可再分发的包。
  • 或者,将 DLL 安装到应用程序本地目录(直接复制到安装应用程序的目录中)或静态链接到 CRT。在此情况下,将需要手动为 CRT 提供服务。

对于打印机驱动程序:

  • 这些驱动程序应在 INF 中包括需要的 CRT,以便将 CRT 文件作为驱动程序预加载的一部分复制到驱动程序存储。
  • V4 打印驱动程序无法使用辅助安装程序进行安装,所以 INF 必须将 C/C++ 运行时库的相关二进制文件复制到驱动程序存储。要这样做,你应在驱动程序包的 [COPY_FILES] 部分引用适当的文件。
  • V3 打印驱动程序不应使用辅助安装程序进行安装,因为它们在“点和打印”连接期间不运行。这些驱动程序应在驱动程序包的 [COPY_FILES] 部分引用适当的文件。

下面是如何在 INF 的 [COPY_FILES] 部分包含 CRT 二进制文件的示例:

[COPY_FILES]
;CRT
Msvcr120.dll
; other files

[SourceDisksFiles]
Msvcr120.dll = 2 
; other files

[SourceDisksNames.amd64]
1 = %Location%,,,
2 = %Location%,,,"amd64"

对于 UMDF 驱动程序:

  • 针对 CRT 静态链接驱动程序,以便在二进制文件中包含运行时。在此情况下,你不需要再分发 CRT。

将代码与 C 运行时库相链接

以下库包含 C 运行时库函数。

术语 描述

Msvcr120.dll

C 运行时。

Msvcp120.dll

C++ 运行时。

Msvcr120d.dll

C 运行时的调试版本。不允许再分发。

Msvcp120d.dll

C++ 运行时的调试版本。不允许再分发。

 

要确定哪些 DLL 必须与应用程序一起分发,应收集应用程序依赖的 DLL 列表。收集该列表的一种方法是运行依赖关系查看器 (depends.exe)。

如果你有依赖关系列表,则将它与在适用于 Visual Studio 2013 Preview 和 Visual Studio 2013 SDK Preview 的可再分发的代码中描述的文件列表相比较。有关详细信息,请参阅确定要再分发哪些 DLL选择部署方法

你无法再分发在 Visual Studio 中包含的所有文件;仅允许你再分发在适用于 Visual Studio 2013 Preview 和 Visual Studio 2013 SDK Preview 的可再分发的代码中指定的文件。应用程序的调试版本和各种 Visual C++ 动态链接库不可再分发。

总结 - 你需要做的事项

如果可以,则将 Visual C++ Redistributable Package(VCRedist_x86.exe、VCRedist_x64.exe 和 VCRedist_arm.exe)VCRedist.msi 用作安装过程的一部分。

对于打印机驱动程序,将 CRT 的桌面应用程序本地部署用于驱动程序存储。

对于 UMDF 驱动程序,在驱动程序代码中使用 CRT 的静态链接。

相关主题

确定要再分发哪些 DLL

适用于 Visual Studio 2013 Preview 和 Visual Studio 2013 SDK Preview 的可再发分的代码

选择部署方法