PAYATHON 2026

Visual Studio 2015 无法检测 Windows 10 WDK 的 ntddk.h

排障赵师傅

结论

ntddk.h 是 WDK 提供的内核模式头文件,普通 Windows SDK 并不包含它。出现 C1083,通常说明项目没有使用 WDK 的内核驱动工具集,或当前选择的 SDK 版本缺少对应的 WDK km 目录。

可按以下方式处理:

  1. 在同一台计算机上安装版本对应的 Windows SDK 和 WDK。
  2. 先安装 SDK,再安装 WDK。如果之后安装或修复过 Visual Studio,还要再修复一次 WDK。
  3. 将项目的工具集设为 WindowsKernelModeDriver10.0,由 WDK 属性表配置头文件和库路径。
  4. 不要在项目中直接写入某个 10.0.xxxxx.0\km 目录。
  5. 如果各开发机安装的版本不同,应在构建前查找完整的 SDK/WDK 版本,并通过 WindowsTargetPlatformVersion 传给 MSBuild。

仅仅安装了某个 Windows 10 SDK 和某个 Windows 10 WDK,项目仍未必能够构建。两者虽然共用 Windows Kits\10 目录,但并非任意版本都能配套使用。

为什么会找不到 ntddk.h

ntddk.h 的典型安装路径是:

C:\Program Files (x86)\Windows Kits\10\Include\<version>\km\ntddk.h

普通桌面 C++ 项目通常只会包含 ucrt、um、shared 等 SDK 目录,不会自动加入 WDK 的 km 目录。WDK 驱动工具集还会配置内核模式需要的预处理宏、编译参数和库,所以只在“附加包含目录”中补上一个 km 路径,无法完整修复构建环境。

版本目录不完整也会导致这个错误。例如,项目选择了 10.0.15063.0,但这个版本的目录中只有 SDK 的 um 和 shared,ntddk.h 却位于另一个版本的 km 目录。编译器仍会到下面的路径查找:

...\Include\10.0.15063.0\km\ntddk.h

这个目录不存在时,就会产生 C1083。

先检查实际安装状态

在命令提示符中执行:

dir "%ProgramFiles(x86)%\Windows Kits\10\Include\*\km\ntddk.h"

正常情况下,命令至少应返回一个实际文件。同时检查该版本下是否有 shared 等配套目录,例如:

Include
└── 10.0.xxxxx.0
    ├── km
    │   └── ntddk.h
    ├── shared
    ├── ucrt
    └── um

如果完全找不到 ntddk.h,说明 WDK 没有正确安装,或安装内容不完整。此时调整 Visual Studio 的包含目录没有作用,应先修复或重新安装 WDK。

如果文件存在,而 Visual Studio 仍然报错,就要继续检查项目使用的工具集。

正确配置 Visual Studio 2015 项目

建议使用 WDK 安装后提供的驱动项目模板创建项目。对于已有项目,至少要改用 WDK 工具集。相关 .vcxproj 配置通常如下:

<PropertyGroup
  Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"
  Label="Configuration">
  <ConfigurationType>Driver</ConfigurationType>
  <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
  <DriverType>WDM</DriverType>
</PropertyGroup>

DriverType 要根据项目类型设置,例如 WDM、KMDF 或其他受支持的类型。不要为了找到头文件而随意更改驱动模型。

可以在 Visual Studio 中逐项检查:

  1. 打开“项目属性”。
  2. 进入“配置属性”中的“常规”。
  3. 确认“平台工具集”是 WindowsKernelModeDriver10.0。
  4. 确认当前项目是驱动项目,不是普通应用程序或 DLL 项目。
  5. 检查“VC++ 目录”和“C/C++ → 常规 → 附加包含目录”,删除手工填写的具体 SDK 版本路径。

如果工具集列表中没有 WindowsKernelModeDriver10.0,通常是 WDK 的 Visual Studio 集成没有安装成功。关闭 Visual Studio,运行 WDK 安装程序并执行修复。WDK 应当在 Visual Studio 及其 C++ 组件安装完成后安装或修复。

处理 SDK 与 WDK 版本不一致

一台机器可以并存多个 SDK 和 WDK 版本,无需为了安装新版本而删除旧版本。不过,驱动构建所选的版本必须同时包含所需的 SDK 和 WDK 内容。

假设机器上只有以下目录:

Include\10.0.14393.0\km
Include\10.0.14393.0\shared
Include\10.0.15063.0\shared
Include\10.0.15063.0\um

由于缺少对应的 km 目录,10.0.15063.0 不能作为完整的驱动构建版本。项目应改用内容完整的 10.0.14393.0 工具链,或者安装与目标 SDK 配套的 WDK。

不要把 10.0.14393.0 直接写入“附加包含目录”。如果团队需要固定构建版本,应在统一的构建配置和环境准备脚本中指定版本,并确保所有开发机和 CI 都安装了该版本。这样比各台机器自行选择版本更容易保证构建结果可重复。

不硬编码版本的自动检测方案

如果业务允许各台机器使用不同版本的 WDK,可以让构建脚本查找头文件完整的最高版本,再将版本号传给 MSBuild:

$includeRoot = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\Include"

$candidate = Get-ChildItem $includeRoot -Directory |
    Where-Object {
        (Test-Path (Join-Path $_.FullName "km\ntddk.h")) -and
        (Test-Path (Join-Path $_.FullName "shared\ntdef.h")) -and
        (Test-Path (Join-Path $_.FullName "um\Windows.h"))
    } |
    Sort-Object { [version]$_.Name } -Descending |
    Select-Object -First 1

if ($null -eq $candidate) {
    throw "未找到同时包含 km、shared 和 um 头文件的 Windows 10 SDK/WDK。"
}

$targetVersion = $candidate.Name

& msbuild.exe Driver.sln `
    /p:Configuration=Debug `
    /p:Platform=x64 `
    /p:WindowsTargetPlatformVersion=$targetVersion

if ($LASTEXITCODE -ne 0) {
    exit $LASTEXITCODE
}

这段脚本无需固定版本号,但只能确认头文件目录基本完整。正式构建前,还要检查目标架构需要的 WDK 库,例如:

Windows Kits\10\Lib\<version>\km\x64

团队如果依赖特定的 KMDF、UMDF 或签名工具,也要将这些内容加入检测范围。

查看 MSBuild 最终使用的路径

如果错误仍未解决,可以在 Visual Studio Developer Command Prompt 中生成详细日志:

msbuild Driver.vcxproj /p:Configuration=Debug /p:Platform=x64 /v:diag > build.log
findstr /i "WindowsTargetPlatformVersion WindowsSdkDir ntddk.h" build.log

通过日志可以确认:

  • WindowsTargetPlatformVersion 最终使用的值;
  • WDK 属性表是否已加载;
  • 编译器的 /I 参数中是否包含对应版本的 km 和 shared;
  • 项目文件或用户属性表是否覆盖了工具集设置。

如果 /I 参数中完全没有 km,先检查项目类型和 PlatformToolset。如果参数中有 km,对应的版本目录却不存在,说明目标版本与已安装的 WDK 不一致。

注意事项

Visual Studio 编辑器中的红色波浪线可能来自 IntelliSense 缓存,但 fatal error C1083 是实际的编译器错误。排查时应以构建命令中的 /I 参数为准。

不要通过复制 ntddk.h、创建软链接,或混用不同版本的 km、shared 和库目录来构建内核代码。即使头文件可以通过编译,也不能说明 ABI、库文件和驱动工具链已经匹配。

团队如果要求构建稳定且可复现,建议固定一组经过验证的 Visual Studio、SDK 和 WDK 版本,再由安装脚本检查依赖。动态选择版本适合兼容范围较宽的项目,但仍需进行工具链兼容性测试。

备注:内容仅供参考。