Visual Studio 2015 无法检测 Windows 10 WDK 的 ntddk.h
结论
ntddk.h 是 WDK 提供的内核模式头文件,普通 Windows SDK 并不包含它。出现 C1083,通常说明项目没有使用 WDK 的内核驱动工具集,或当前选择的 SDK 版本缺少对应的 WDK km 目录。
可按以下方式处理:
- 在同一台计算机上安装版本对应的 Windows SDK 和 WDK。
- 先安装 SDK,再安装 WDK。如果之后安装或修复过 Visual Studio,还要再修复一次 WDK。
- 将项目的工具集设为
WindowsKernelModeDriver10.0,由 WDK 属性表配置头文件和库路径。 - 不要在项目中直接写入某个
10.0.xxxxx.0\km目录。 - 如果各开发机安装的版本不同,应在构建前查找完整的 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 中逐项检查:
- 打开“项目属性”。
- 进入“配置属性”中的“常规”。
- 确认“平台工具集”是
WindowsKernelModeDriver10.0。 - 确认当前项目是驱动项目,不是普通应用程序或 DLL 项目。
- 检查“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 版本,再由安装脚本检查依赖。动态选择版本适合兼容范围较宽的项目,但仍需进行工具链兼容性测试。
备注:内容仅供参考。
