diff --git a/Build-Samples.ps1 b/Build-Samples.ps1 index 7eafb54d4..a73a2afa1 100644 --- a/Build-Samples.ps1 +++ b/Build-Samples.ps1 @@ -7,7 +7,7 @@ 1. Ensures a developer build environment (VS DevShell or EWDK) is active 2. Discovers samples via ListAllSamples.ps1 (or uses the -Samples parameter if provided) - 3. Detects the build environment (GitHub CI, NuGet, EWDK, or WDK) and build number + 3. Resolves the build environment (auto-detected or forced via -RunMode) and build number 4. Loads exclusions from exclusions.csv (supports wildcard paths) 5. Builds all non-excluded sample/configuration/platform combinations in parallel 6. Generates CSV and HTML overview reports @@ -38,6 +38,10 @@ Additional InfVerif options (e.g. '/samples', '/msft'). If not provided, determined automatically based on the WDK build number. +.PARAMETER RunMode + Selects the build environment mode. Valid values: Auto, WDK, NuGet, EWDK. + Defaults to 'Auto', which detects the environment automatically (NuGet → EWDK → WDK). + .PARAMETER ThrottleLimit Maximum parallel build jobs. Defaults to 5 x logical processors. @@ -60,6 +64,11 @@ .\Build-Samples -ThrottleLimit 8 Discovers all samples and builds them with limited parallelism. + +.EXAMPLE + .\Build-Samples -RunMode WDK + + Forces WDK mode regardless of environment variables. #> #Requires -Version 7.0 @@ -72,6 +81,8 @@ param( [string]$LogFilesDirectory = (Join-Path (Get-Location) "_logs"), [string]$ReportFileName = $(if ([string]::IsNullOrEmpty($env:WDS_ReportFileName)) { "_overview" } else { $env:WDS_ReportFileName }), [string]$InfOptions, + [ValidateSet('Auto', 'WDK', 'NuGet', 'EWDK')] + [string]$RunMode = 'Auto', [int]$ThrottleLimit = 0 ) @@ -79,108 +90,7 @@ param( # Helper Functions # ============================================================================= -function Initialize-DevShell { - <# - .SYNOPSIS Imports the Visual Studio Developer PowerShell if not already active. - #> - param([string]$ReturnToDirectory) - - if ($env:VSCMD_VER) { - Write-Verbose "VS Developer Shell already active (VSCMD_VER=$env:VSCMD_VER)." - return - } - - $devShellDll = Resolve-Path "$env:ProgramFiles\Microsoft Visual Studio\*\*\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" ` - -ErrorAction SilentlyContinue | Select-Object -First 1 - if (-not $devShellDll) { - Write-Error "Visual Studio Developer Shell module not found." - exit 1 - } - - Import-Module $devShellDll.Path - $vsInstall = Resolve-Path "$env:ProgramFiles\Microsoft Visual Studio\*\*" | Select-Object -First 1 - Enter-VsDevShell -VsInstallPath $vsInstall.Path - Set-Location $ReturnToDirectory -} - -function Assert-MsBuildAvailable { - <# - .SYNOPSIS Verifies msbuild.exe is on PATH. Exits with error if not found. - #> - $savedPref = $ErrorActionPreference - $ErrorActionPreference = 'Stop' - try { - Get-Command 'msbuild' | Out-Null - } - catch { - Write-Error "msbuild cannot be called from current environment. Ensure it is on PATH (run from VS Developer Command Prompt or EWDK)." - exit 1 - } - finally { - $ErrorActionPreference = $savedPref - } -} - -function Resolve-BuildEnvironment { - <# - .SYNOPSIS - Detects the active build environment and returns metadata. - .DESCRIPTION - Checks (in priority order) for GitHub CI, local NuGet packages, EWDK, or WDK. - Returns a hashtable: Name, BuildNumber (int), NuGetVersion, WdkVsComponentVersion. - #> - param([string]$RepoRoot) - - $result = @{ - Name = '' - BuildNumber = [int]0 - NuGetVersion = '' - WdkVsComponentVersion = '' - } - - if ($env:GITHUB_REPOSITORY) { - $result.Name = 'GitHub' - $wdkPackage = Get-ChildItem "$RepoRoot\packages\*WDK.x64*" -Name -ErrorAction SilentlyContinue - $result.NuGetVersion = ([regex]'(?<=x64\.)(\d+\.){3}\d+').Match($wdkPackage).Value - $result.BuildNumber = [int]($result.NuGetVersion.Split('.')[2]) - } - elseif (Test-Path "$RepoRoot\packages\*") { - $result.Name = 'NuGet' - $wdkPackage = Get-ChildItem "$RepoRoot\packages\*WDK.x64*" -Name -ErrorAction SilentlyContinue - $result.NuGetVersion = ([regex]'(?<=x64\.)(\d+\.){3}\d+').Match($wdkPackage).Value - $result.BuildNumber = [int]($result.NuGetVersion.Split('.')[2]) - } - elseif ($env:BuildLab -match '^(?[^.]+)\.(?\d+)\.(?[^.]+)$') { - $result.Name = "EWDK.$($Matches.branch).$($Matches.build).$($Matches.qfe)" - $result.BuildNumber = [int]$Matches.build - } - elseif ($env:UCRTVersion -match '10\.0\.(?\d+)\.0') { - $result.Name = 'WDK' - $result.BuildNumber = [int]$Matches.build - } - else { - Write-Output "Environment variables {" - Get-ChildItem env:* | Sort-Object Name - Write-Output "Environment variables }" - Write-Error "Could not determine build environment. Ensure EWDK, WDK, or NuGet packages are configured." - exit 1 - } - - # WDK VS component version (EWDK does not ship this metadata) - if ($result.Name -match '^EWDK') { - $result.WdkVsComponentVersion = '(not available for EWDK builds)' - } - else { - $vsComponent = Get-ChildItem "${env:ProgramData}\Microsoft\VisualStudio\Packages\Microsoft.Windows.DriverKit,version=*" -ErrorAction SilentlyContinue - if (-not $vsComponent) { - Write-Error "WDK Visual Studio Component not found. Ensure the WDK Component is installed." - exit 1 - } - $result.WdkVsComponentVersion = [regex]::Match($vsComponent.Name, '(\d+\.){3}\d+').Value - } - - return $result -} +. (Join-Path $PSScriptRoot 'BuildEnvironment.ps1') function Import-SampleExclusions { <# @@ -382,9 +292,9 @@ function Build-SingleSample { # Step 1 - Prepare Build Environment # ============================================================================= -$root = (Get-Location).Path - -Initialize-DevShell -ReturnToDirectory $root +$root = (Get-Location).Path +$buildEnv = Resolve-BuildEnvironment -RepoRoot $root -RunMode $RunMode +$buildNumber = $buildEnv.BuildNumber Assert-MsBuildAvailable # ============================================================================= @@ -467,14 +377,7 @@ if ($sampleSet.Count -eq 0) { } # ============================================================================= -# Step 5 - Detect Build Environment -# ============================================================================= - -$buildEnv = Resolve-BuildEnvironment -RepoRoot $root -$buildNumber = $buildEnv.BuildNumber - -# ============================================================================= -# Step 6 - Determine InfVerif Options +# Step 5 - Determine InfVerif Options # ============================================================================= # # Samples must build cleanly, but certain InfVerif warnings are acceptable because @@ -490,13 +393,13 @@ else { } # ============================================================================= -# Step 7 - Load Exclusions +# Step 6 - Load Exclusions # ============================================================================= $exclusions = Import-SampleExclusions -CsvPath (Join-Path $root 'exclusions.csv') -BuildNumber $buildNumber # ============================================================================= -# Step 8 - Print Build Plan +# Step 7 - Print Build Plan # ============================================================================= $combinationsTotal = $sampleSet.Count * $Configurations.Count * $Platforms.Count @@ -529,7 +432,7 @@ Write-Output "" Write-Output "Building all combinations..." # ============================================================================= -# Step 9 - Execute Parallel Builds +# Step 8 - Execute Parallel Builds # ============================================================================= # Shared mutable state protected by a Mutex. This is required because @@ -677,7 +580,7 @@ $stopwatch.Stop() Write-Host "" # ============================================================================= -# Step 10 - Report Failures +# Step 9 - Report Failures # ============================================================================= Write-Output "" @@ -716,7 +619,7 @@ if ($buildState.SporadicSet.Count -gt 0) { } # ============================================================================= -# Step 11 - Final Summary +# Step 10 - Final Summary # ============================================================================= $elapsed = $stopwatch.Elapsed @@ -742,7 +645,7 @@ Write-Output " HTML report: $reportHtmlPath" Write-Output "--------------------------------------------------------------------" # ============================================================================= -# Step 12 - Generate Reports +# Step 11 - Generate Reports # ============================================================================= $sortedResults = $buildState.Results | Sort-Object { $_.Sample } @@ -750,6 +653,6 @@ $sortedResults | ConvertTo-Csv | Out-File $reportCsvPath $sortedResults | ConvertTo-Html -Title "WDK Sample Build Overview" | Out-File $reportHtmlPath # Only open the HTML report interactively (not in CI/automation) -if (-not $env:GITHUB_REPOSITORY -and -not $env:BUILD_BUILDID -and [Environment]::UserInteractive) { +if (-not $env:BUILD_BUILDID -and [Environment]::UserInteractive) { Invoke-Item $reportHtmlPath } diff --git a/BuildEnvironment.ps1 b/BuildEnvironment.ps1 new file mode 100644 index 000000000..bdb90a2eb --- /dev/null +++ b/BuildEnvironment.ps1 @@ -0,0 +1,220 @@ +# BuildEnvironment.ps1 +# Helper functions for detecting and initialising the build environment. +# Dot-sourced by Build-Samples.ps1. + +function Get-VsInstallationsWithWdk { + <# + .SYNOPSIS + Returns all Visual Studio installations that have the WDK component installed. + .DESCRIPTION + Uses vswhere.exe (from its fixed install location under Program Files (x86)) to + enumerate VS installations that carry the Microsoft.Windows.DriverKit component. + If vswhere.exe is not found at the expected path the installed VS version is too + old to be supported and the script exits with an error. + #> + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (-not (Test-Path $vswhere)) { + Write-Error "vswhere.exe was not found at '$vswhere'. Visual Studio 2017 or later is required." + exit 1 + } + + # Full VS editions install the WDK component as 'Microsoft.Windows.DriverKit', + # while Build Tools uses 'Component.Microsoft.Windows.DriverKit.BuildTools'. + # Query for either so both product types are discovered. + $wdkComponentIds = @('Microsoft.Windows.DriverKit', 'Component.Microsoft.Windows.DriverKit.BuildTools') + $allInstallations = @() + foreach ($componentId in $wdkComponentIds) { + $json = & $vswhere -all -products * -format json -requires $componentId -include packages 2>$null + if ($json) { + $allInstallations += ($json | ConvertFrom-Json) + } + } + # Deduplicate by installationPath in case both components are present + $installations = $allInstallations | Sort-Object -Property installationPath -Unique + return $installations | ForEach-Object { + $wdkPackage = $_.packages | Where-Object { $_.id -in $wdkComponentIds } | Select-Object -First 1 + [PSCustomObject]@{ + DisplayName = $_.displayName + InstallationPath = $_.installationPath + WdkVsComponentVersion = $wdkPackage.version + } + } +} + +function Select-VsInstallation { + <# + .SYNOPSIS + Chooses a Visual Studio installation from the list returned by Get-VsInstallationsWithWdk. + .DESCRIPTION + - 0 found : error + exit + - 1 found : verbose log, return it + - 2+ found : display a numbered menu and prompt the user to choose + #> + param([object[]]$Installations) + + if (-not $Installations -or $Installations.Count -eq 0) { + Write-Error "No Visual Studio installation with the required WDK media was found. Ensure the WDK Visual Studio component is installed." + exit 1 + } + + if ($Installations.Count -eq 1) { + Write-Verbose "Found Visual Studio installation with required WDK media: $($Installations[0].DisplayName) at $($Installations[0].InstallationPath)" + return $Installations[0] + } + + # Multiple installations — let the user choose + Write-Host "" + Write-Host "The following Visual Studio installations were found with the required WDK media:" + for ($i = 0; $i -lt $Installations.Count; $i++) { + Write-Host " [$($i + 1)] $($Installations[$i].DisplayName) — $($Installations[$i].InstallationPath)" + } + Write-Host "" + + do { + $choice = Read-Host "Select the installation to use [1-$($Installations.Count)]" + $index = [int]$choice - 1 + } while ($index -lt 0 -or $index -ge $Installations.Count) + + return $Installations[$index] +} + +function Assert-MsBuildAvailable { + <# + .SYNOPSIS Verifies msbuild.exe is on PATH. Exits with error if not found. + #> + $savedPref = $ErrorActionPreference + $ErrorActionPreference = 'Stop' + try { + Get-Command 'msbuild' | Out-Null + } + catch { + Write-Error "msbuild cannot be called from current environment. Ensure it is on PATH (run from VS Developer Command Prompt or EWDK)." + exit 1 + } + finally { + $ErrorActionPreference = $savedPref + } +} + +function Resolve-BuildEnvironment { + <# + .SYNOPSIS + Detects the active build environment, opens a VS Developer Shell when needed, + and returns metadata about the environment. + .DESCRIPTION + Handles the full setup sequence in one place: + 1. Detect mode: EWDK → NuGet → WDK (Auto), or use the explicitly supplied RunMode. + 2. For NuGet / WDK: open a VS Developer Shell if one is not already active, + prompting the user to choose if multiple VS installations with the required + WDK media are found. If the shell is already active, the matching installation + is located via $env:VSINSTALLDIR. + 3. For EWDK: skip VS detection entirely ($env:BuildLab is the authoritative signal). + Returns a hashtable: Name, BuildNumber (int), NuGetVersion, WdkVsComponentVersion. + #> + param( + [string]$RepoRoot, + [string]$RunMode = 'Auto' + ) + + $result = @{ + Name = '' + BuildNumber = [int]0 + NuGetVersion = '' + WdkVsComponentVersion = '' + } + + # ------------------------------------------------------------------------- + # Step 1 – Detect / validate build mode + # ------------------------------------------------------------------------- + + # EWDK: checked first. $env:BuildLab is an active, explicit signal that + # disappears when you close the EWDK prompt, unlike the packages\ folder. + if ($RunMode -eq 'EWDK' -or + ($RunMode -eq 'Auto' -and $env:BuildLab -match '^(?[^.]+)\.(?\d+)\.(?[^.]+)$')) { + + if ($RunMode -eq 'EWDK' -and + $env:BuildLab -notmatch '^(?[^.]+)\.(?\d+)\.(?[^.]+)$') { + Write-Error "RunMode is 'EWDK' but the EWDK environment variable BuildLab is not set. Ensure the EWDK is mounted and the environment is initialised." + exit 1 + } + # Re-run the match to populate $Matches (the Auto branch already matched above; + # the forced-EWDK branch needs an explicit match after the validation guard). + $null = $env:BuildLab -match '^(?[^.]+)\.(?\d+)\.(?[^.]+)$' + $result.Name = "EWDK.$($Matches.branch).$($Matches.build).$($Matches.qfe)" + $result.BuildNumber = [int]$Matches.build + $result.WdkVsComponentVersion = '(not available for EWDK builds)' + return $result + } + + $isNuGet = ($RunMode -eq 'NuGet') -or + ($RunMode -eq 'Auto' -and (Test-Path "$RepoRoot\packages\*")) + + if ($RunMode -eq 'NuGet' -and -not (Test-Path "$RepoRoot\packages\*")) { + Write-Error "RunMode is 'NuGet' but no packages were found under '$RepoRoot\packages\'. Ensure NuGet restore has been run." + exit 1 + } + + # If not EWDK and not NuGet, assume WDK. VS Dev Shell setup below will validate + # the environment; if no VS with WDK media is found, Select-VsInstallation errors out. + + # ------------------------------------------------------------------------- + # Step 2 – Set up VS Developer Shell + # ------------------------------------------------------------------------- + + $vsInstall = $null + + if (-not $env:VSCMD_VER) { + # Dev Shell not active – open one now. + $vsInstall = Select-VsInstallation (Get-VsInstallationsWithWdk) + $devShellDll = Join-Path $vsInstall.InstallationPath 'Common7\Tools\Microsoft.VisualStudio.DevShell.dll' + if (-not (Test-Path $devShellDll)) { + Write-Error "Visual Studio Developer Shell module not found at '$devShellDll'." + exit 1 + } + Import-Module $devShellDll + Enter-VsDevShell -VsInstallPath $vsInstall.InstallationPath + Set-Location $RepoRoot + } + else { + Write-Verbose "VS Developer Shell already active (VSCMD_VER=$env:VSCMD_VER)." + # Locate the matching installation via VSINSTALLDIR so we can read its + # WdkVsComponentVersion without prompting the user again. + # Normalize trailing backslash: VSINSTALLDIR ends with '\', vswhere paths do not. + $normalizedVsInstallDir = $env:VSINSTALLDIR.TrimEnd('\') + $vsInstall = Get-VsInstallationsWithWdk | + Where-Object { $_.InstallationPath.TrimEnd('\') -eq $normalizedVsInstallDir } | + Select-Object -First 1 + if (-not $vsInstall) { + Write-Error "The active Visual Studio Developer Shell ('$env:VSINSTALLDIR') does not have the required WDK media installed. Ensure the WDK Visual Studio component is installed." + exit 1 + } + } + + # ------------------------------------------------------------------------- + # Step 3 – Fill mode-specific fields (Dev Shell is now guaranteed active) + # ------------------------------------------------------------------------- + + if ($isNuGet) { + $result.Name = 'NuGet' + $wdkPackage = Get-ChildItem "$RepoRoot\packages\*WDK.x64*" -Name -ErrorAction SilentlyContinue + $result.NuGetVersion = ([regex]'(?<=x64\.)(\d+\.){3}\d+').Match($wdkPackage).Value + $result.BuildNumber = [int]($result.NuGetVersion.Split('.')[2]) + } + else { + # WDK – Dev Shell is now active, UCRTVersion must be set. + if ($env:UCRTVersion -notmatch '10\.0\.(?\d+)\.0') { + Write-Error "UCRTVersion ('$env:UCRTVersion') is not set or does not match the expected format. Ensure the VS Developer Shell is active." + exit 1 + } + $result.Name = 'WDK' + $result.BuildNumber = [int]$Matches.build + } + + if (-not $vsInstall.WdkVsComponentVersion) { + Write-Error "Could not determine WDK component version for '$($vsInstall.DisplayName)'. Ensure the WDK Visual Studio component is installed." + exit 1 + } + $result.WdkVsComponentVersion = $vsInstall.WdkVsComponentVersion + + return $result +} diff --git a/Building-Locally.md b/Building-Locally.md index 645e9a615..9d683a86a 100644 --- a/Building-Locally.md +++ b/Building-Locally.md @@ -1,165 +1,56 @@ -# How to build locally +# Building Driver Samples Locally -## Step 1: Install Tools +## Prerequisites -```powershell -winget install --id Microsoft.Powershell --source winget -winget install --id Git.Git --source winget -``` +### Required tools -For using WDK NuGet feed based build additionally: +Install PowerShell and Git if you don't have them already: ```powershell -winget install --id Microsoft.NuGet --source winget -``` - ---- - -## Step 2: Optional: Disable Strong Name Validation - -When: This step is only required if you will be using pre-release versions of the WDK. - -As per https://learn.microsoft.com/en-us/windows-hardware/drivers/installing-preview-versions-wdk : - -Run the following commands from an elevated command prompt to disable strong name validation: - -``` -reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,31bf3856ad364e35 /v TestPublicKey /t REG_SZ /d 00240000048000009400000006020000002400005253413100040000010001003f8c902c8fe7ac83af7401b14c1bd103973b26dfafb2b77eda478a2539b979b56ce47f36336741b4ec52bbc51fecd51ba23810cec47070f3e29a2261a2d1d08e4b2b4b457beaa91460055f78cc89f21cd028377af0cc5e6c04699b6856a1e49d5fad3ef16d3c3d6010f40df0a7d6cc2ee11744b5cfb42e0f19a52b8a29dc31b0 /f - -reg add HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,31bf3856ad364e35 /v TestPublicKey /t REG_SZ /d 00240000048000009400000006020000002400005253413100040000010001003f8c902c8fe7ac83af7401b14c1bd103973b26dfafb2b77eda478a2539b979b56ce47f36336741b4ec52bbc51fecd51ba23810cec47070f3e29a2261a2d1d08e4b2b4b457beaa91460055f78cc89f21cd028377af0cc5e6c04699b6856a1e49d5fad3ef16d3c3d6010f40df0a7d6cc2ee11744b5cfb42e0f19a52b8a29dc31b0 /f +winget install --id Microsoft.Powershell --source winget +winget install --id Git.Git --source winget ``` ---- - -## Step 3: Optional: Install Microsoft .NET Framework 4.7.2 Targeting Pack and Microsoft .NET Framework 4.8.1 SDK +### Install a supported version of the WDK -When: This step is only required to build sample usb\usbview . +See [Download the Windows Driver Kit (WDK)](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) for all available installation options (NuGet packages, MSI installer, EWDK ISO). -### Option A: Install VS Components - -Easy: If you will install Visual Studio (see later) you may at that point select to add both of following individual components: -* .NET Framework 4.7.2 targeting pack -* .NET Framework 4.8.1 SDK - -### Option B: Use EWDK - -Easy: If you use EWDK, then all necessary prequisites are included. - -### Option C: Install Developer Pack - -Hardest: Install from https://aka.ms/msbuild/developerpacks -> '.NET Framework' -> 'Supported versions' both of following packages: -* .NET Framework 4.7.2 -> Developer Pack -* .NET Framework 4.8.1 -> Developer Pack - -This will install following Apps: -* Microsoft .NET Framework 4.7.2 SDK -* Microsoft .NET Framework 4.7.2 Targeting Pack -* Microsoft .NET Framework 4.7.2 Targeting Pack (ENU) -* Microsoft .NET Framework 4.8.1 SDK -* Microsoft .NET Framework 4.8.1 Targeting Pack -* Microsoft .NET Framework 4.8.1 Targeting Pack (ENU) - ---- - -## Step 4: Clone Windows Driver Samples and checkout relevant branch +### Clone the repository ```powershell -cd "path\to\your\repos" git clone --recurse-submodules "https://github.com/microsoft/Windows-driver-samples.git" cd ".\Windows-driver-samples" ``` -If you are planning to use in-market WDK, then you would typically want to use the 'main' branch: - -``` -git checkout main -``` - -If you are planning to use a WDK Preview or WDK EEAP release, then you would typically want to use the 'develop' branch: - -``` -git checkout develop -``` - ---- - -## Step 5: Create a "driver build environment" - -To build the Windows Driver Samples you need a "driver build environment". In essence an environment that consist of following prerequisites: -* Visual Studio Build Tools including tools such as for example cl.exe and link.exe . -* The Windows Software Development Kit. -* The Windows Driver Kit. +### Environment specific requisites -### Option A: Use WDK NuGet Packages - -* See [Download the Windows Driver Kit (WDK)](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) for instructions on how to install Visual Studio, but only complete `Step 1`. You do not need to install the SDK or the WDK. -* Launch a "Developer Command Prompt for VS 2022". -* Restore WDK packages from feed : +- If you are using the WDK via **NuGet**: install NuGet and restore the packages: ```powershell -cd "path\to\your\repos\Windows-driver-samples" +winget install --id Microsoft.NuGet --source winget nuget restore -PackagesDirectory ".\packages" ``` -* When this is done you should have a .\packages folder that looks like example below: +- If you are using the WDK via **EWDK**: mount the EWDK ISO, open a terminal in the mounted drive, and launch the build environment: ```powershell -cd "path\to\your\repos\Windows-driver-samples" -dir /b packages -Microsoft.Windows.SDK.CPP.10.0.26000.1 -Microsoft.Windows.SDK.CPP.x64.10.0.26000.1 -Microsoft.Windows.SDK.CPP.arm64.10.0.26000.1 -Microsoft.Windows.WDK.x64.10.0.26000.1 -Microsoft.Windows.WDK.arm64.10.0.26000.1 +.\LaunchBuildEnv ``` -### Option B: Use the Windows Driver Kit - -* Here you will install each of above prerequisites one at a time. -* See [Download the Windows Driver Kit (WDK)](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) for instructions on how to install Visual Studio, SDK, and WDK. -* Launch a "Developer Command Prompt for VS 2022". - -### Option C: Use an Enterprise WDK - -* You can also simply use the Enterprise WDK (EWDK), a standalone, self-contained command-line environment for building drivers that contains all prerequisites in one combined ISO. -* See [Download the Windows Driver Kit (WDK)](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) for instructions on how to download the EWDK. -* Mount ISO image -* Open a terminal -* `.\LaunchBuildEnv` --- -## Step 6: Build all samples +## Building the Samples -```powershell -pwsh -.\Build-Samples -``` -Above builds all samples for all configurations and platforms. - -You can refine what exact samples to build, what configurations, and platforms to build. Here are a few examples: +The `Build-Samples.ps1` script auto-detects which WDK environment is active and will build all the samples with all the configurations by default. Just run the following command from **PowerShell**: ```powershell -# Get Help: -Get-Help .\Build-Samples - -# Build all solutions for all flavors with builds running in parallel: -.\Build-Samples - -# Build with Verbose output (print start and finish of each sample): -.\Build-Samples -Verbose - -# Build without massive parallelism (slow, but good for debugging): -.\Build-Samples -ThrottleLimit 1 - -# Build all samples inside the 'tools' folder using wildcards: -.\Build-Samples -Samples 'tools.*' - -# Build specific samples for only 'Debug|x64': -.\Build-Samples -Samples 'tools.sdv.samples.sampledriver' -Configurations 'Debug' -Platforms 'x64' +.\Build-Samples.ps1 ``` -Example of expected output: +--- + +## Expected Output ``` --- WDK Sample Build Plan ------------------------------------------ @@ -209,31 +100,76 @@ Building all combinations... --- -## 7: NuGet - Additional Notes +## Ways to Run + +```powershell +# Show full parameter reference: +Get-Help .\Build-Samples.ps1 -Detailed + +# Build everything (all samples, configurations, platforms): +.\Build-Samples.ps1 + +# Verbose output — prints start/finish of each sample: +.\Build-Samples.ps1 -Verbose + +# Limit parallelism (useful for debugging build failures): +.\Build-Samples.ps1 -ThrottleLimit 1 + +# Build only samples inside the 'tools' folder: +.\Build-Samples.ps1 -Samples 'tools.*' + +# Build a specific sample for Debug|x64 only: +.\Build-Samples.ps1 -Samples 'tools.sdv.samples.sampledriver' -Configurations 'Debug' -Platforms 'x64' +``` + +--- + +## Additional Notes + +### Pre-release WDK: disable strong name validation + +Required only when using pre-release WDK versions. Run from an elevated command prompt: + +``` +reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,31bf3856ad364e35 /v TestPublicKey /t REG_SZ /d 00240000048000009400000006020000002400005253413100040000010001003f8c902c8fe7ac83af7401b14c1bd103973b26dfafb2b77eda478a2539b979b56ce47f36336741b4ec52bbc51fecd51ba23810cec47070f3e29a2261a2d1d08e4b2b4b457beaa91460055f78cc89f21cd028377af0cc5e6c04699b6856a1e49d5fad3ef16d3c3d6010f40df0a7d6cc2ee11744b5cfb42e0f19a52b8a29dc31b0 /f + +reg add HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,31bf3856ad364e35 /v TestPublicKey /t REG_SZ /d 00240000048000009400000006020000002400005253413100040000010001003f8c902c8fe7ac83af7401b14c1bd103973b26dfafb2b77eda478a2539b979b56ce47f36336741b4ec52bbc51fecd51ba23810cec47070f3e29a2261a2d1d08e4b2b4b457beaa91460055f78cc89f21cd028377af0cc5e6c04699b6856a1e49d5fad3ef16d3c3d6010f40df0a7d6cc2ee11744b5cfb42e0f19a52b8a29dc31b0 /f +``` + +See [Installing preview versions of the WDK](https://learn.microsoft.com/en-us/windows-hardware/drivers/installing-preview-versions-wdk) for more details. -To restore a specific version of our WDK NuGet packages: +### Building `usb\usbview`: .NET Framework targeting packs -Follow these steps before running "nuget restore" command: -* Open the .\packages.config file and update the full version (including the branch if required) in all three entries. -* Open the .\Directory.build.props file and update the version and build of the package with the same values as in previous step. -* Open .\Build-Samples.ps1 and check the NuGet build number logic (used by .\exclusions.csv and for determining infverif flags) -* Now you can run "nuget restore" +The `usb\usbview` sample requires .NET Framework 4.7.2 and 4.8.1. Choose one option: -A few examples of how to interact with nuget: +- **VS installer** — add the *.NET Framework 4.7.2 targeting pack* and *.NET Framework 4.8.1 SDK* individual components when installing Visual Studio. +- **EWDK** — all required prerequisites are already included. +- **Manual** — download both Developer Packs from https://aka.ms/msbuild/developerpacks. + +### NuGet: restoring a specific WDK version + +To pin a specific WDK NuGet version before running `nuget restore`: + +1. Open `.\packages.config` and update the version in all entries. +2. Open `.\Directory.build.props` and set the same version. +3. Run `nuget restore -PackagesDirectory ".\packages"`. + +Useful NuGet commands: ```powershell -# To add an alternative online NuGet source: -nuget sources add -Name "MyNuGetFeed" -Source "https://nugetserver.com/_packaging/feedname/nuget/v3/index.json" +# Add an online feed: +nuget sources add -Name "MyFeed" -Source "https://nugetserver.com/_packaging/feedname/nuget/v3/index.json" -# To add an alternative local NuGet source: -nuget sources add -Name "MyNuGetFeed" -Source "\\path\to\mylocalrepo" +# Add a local feed: +nuget sources add -Name "MyFeed" -Source "\\path\to\mylocalrepo" -# To remove an alternative NuGet source: -nuget sources remove -Name "MyNuGetFeed" +# Remove a feed: +nuget sources remove -Name "MyFeed" -# To enumerate NuGet locals: +# List local caches: nuget locals all -list -# To clear NuGet locals: +# Clear local caches: nuget locals all -clear ``` +