如何以编程方式检测和定位Windows 10 SDK?

时间:2016-01-31 20:42:20

标签: windows visual-studio winapi sdk windows-10

TL; DR

是否有Windows注册表项(或其他易于编程的方式)来查找&检测适用于SDK V10.0的Windows SDK?

我正在做与this类似的事情,使用Windows 10 SDK附带的一些工具。

我正在寻找一种以编程方式检测和定位Windows SDK 。此技术必须适用于(至少)10.0版本(此问题的当前版本)。最好是,我想要一种适用于所有版本的技术(世界和平也会很好)。

Previous versions(至少达到V8.1A - 与Visual Studio 2013一样)可以通过Windows注册表检测到。 (虽然V <7.0 may not have been)。

对于64位安装: HKEY_LOCAL_MACHINE\SOFTWARE\ Wow6432Node \Microsoft\Microsoft SDKs\Windows(请注意32位的粗体差异)。

对于32位安装: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\WindowsHKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows

(更多关于MSDN Windows SDK blog)。

但是,V10.0(或Visual Studio 2015中包含的V10.0A)不像以前的版本那样制作注册表项!

using compiler macros种技术可以检测 SDK版本。但是,这些仅仅适用于SDK工具(xsd.exe等)并不实用,因为它们需要整个编译步骤 - 这不一定会产生SDK工具目录的路径!

理想情况下,这应该可以使用PowerShell或批处理脚本或其他一些可以包含在构建脚本或其他自动化环境中的简单方法来实现(毕竟它们是编程工具)。

注意:

有办法通过询问文件系统来实现这一点,( ie 以编程方式列出子目录%ProgramFiles(x86)%\Microsoft SDKs\Windows\,解析'V'和'A'-s并选择所列数字的max()(10.0等)......

,这些方法有许多缺点:

  1. 相当笨重(文件系统访问,字符串解析等)
  2. 容易出错,来自错误卸载的SDK的空文件夹剩余可能会导致所述笨重的目录解析。
  3. 根据路径差异,按平台(x64上的 %ProgramFiles(x86)%,但32位上为%ProgramFiles%)和SDK版本; SDK&lt; 7在Bin目录中找到工具,而SDK&gt; 7使用bin\NETFX X.X tools(注意小写'b',只是为了增加不一致性)。
  4. 还受用户安装选择的限制(例如,“聪明的”系统管理员在C:\ Stuff \ WinSDK \ V10.0 \中安装了SDK)。
  5. 因此以编程方式实现此目标会更好 MUCH ,例如通过注册表(就像possible for previous Windows SDK versions

    此问题与this one不重复,因为此问题都在询问不同的SDK版本,并且还在询问程序化 ie 注册表等)查找SDK路径的方法。

    也不是this的副本,因为该问题专门处理cmake并涉及构建数量不匹配。

3 个答案:

答案 0 :(得分:5)

我没有权威的来源,但它会从Windows 10 SDK的卸载程序中追溯,并在我看过的几台计算机上检出:

HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots
KitsRoot10="C:\Program Files (x86)\Windows Kits\10\"

确切的版本有点难以猜测,因为例如10.0.10150.010.0.10240.010.0.10586.0都是C:\Program Files (x86)\Windows Kits\10\Include下的子目录。

答案 1 :(得分:1)

我的Windows Kits密钥未包含有关v10 Windows SDK的任何信息。但是,我在以下注册表路径中找到了有关它的信息:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\NETFXSDK

在内部,有安装的.NET版本的子键。我有4.64.6.14.6.2

每个密钥都包含一个值InstallationFolder,它指向安装SDK的文件夹(这将是C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\),以及一个值KitsInstallationFolder,其中包含指向包含库(C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\)的工具包。

更有趣的是(至少对我来说),每个键还包含三个键:WinSDK-NetFx40ToolsWinSDK-NetFx40Tools-x64WinSDK-NetFx40Tools-x86。每个键的值都为InstallationFolder,其中包含指定SDK版本的tools文件夹的绝对路径。

因此,对于我的用例,我现在在PowerShell中执行以下操作以将文件夹转到最新的SDK工具:

$WindowsSdkToolsPath = gci 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\NETFXSDK' |
    select -Last 1 |
    gci | ? { $_.PSChildName -eq 'WinSDK-NetFx40Tools' } |
    Get-ItemPropertyValue -Name InstallationFolder

答案 2 :(得分:0)

到目前为止,我发现的最好方法是查看Visual Studio的dev命令是如何做到的。当前(2019年)可以在Visual Studio目录的winsdk.bat下的.\Common7\Tools\vsdevcmd\core\中找到。如果将来再次更改,这将有所帮助。即使winsdk.bat被重命名或重组,希望仍然会包含类似的脚本。

在我的系统上,相关部分当前如下所示:

:GetWin10SdkDir

call :GetWin10SdkDirHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1
if errorlevel 1 call :GetWin10SdkDirHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1
if errorlevel 1 call :GetWin10SdkDirHelper HKLM\SOFTWARE > nul 2>&1
if errorlevel 1 call :GetWin10SdkDirHelper HKCU\SOFTWARE > nul 2>&1
if errorlevel 1 exit /B 1
exit /B 0


:GetWin10SdkDirHelper

@REM `Get Windows 10 SDK installed folder`
for /F "tokens=1,2*" %%i in ('reg query "%1\Microsoft\Microsoft SDKs\Windows\v10.0" /v "InstallationFolder"') DO (
    if "%%i"=="InstallationFolder" (
        SET WindowsSdkDir=%%~k
    )
)

@REM `get windows 10 sdk version number`
setlocal enableDelayedExpansion

@REM `Due to the SDK installer changes beginning with the 10.0.15063.0 (RS2 SDK), there is a chance that the
@REM Windows SDK installed may not have the full set of bits required for all application scenarios.
@REM We check for the existence of a file we know to be included in the "App" and "Desktop" portions
@REM of the Windows SDK, depending on the Developer Command Prompt's -app_platform configuration.
@REM If "windows.h" (UWP) or "winsdkver.h" (Desktop) are not found, the directory will be skipped as
@REM a candidate default value for [WindowsSdkDir].`
set __check_file=winsdkver.h
if /I "%VSCMD_ARG_APP_PLAT%"=="UWP" set __check_file=Windows.h

if not "%WindowsSdkDir%"=="" for /f %%i IN ('dir "%WindowsSdkDir%include\" /b /ad-h /on') DO (
    @REM `Skip if Windows.h|winsdkver (based upon -app_platform configuration) is not found in %%i\um.`
    if EXIST "%WindowsSdkDir%include\%%i\um\%__check_file%" (
        set result=%%i
        if "!result:~0,3!"=="10." (
            set SDK=!result!
            if "!result!"=="%VSCMD_ARG_WINSDK%" set findSDK=1
        )
    )
)