Wsl-Instance/Wsl-Instance.Helpers.ps1
# Copyright 2022 Antoine Martin # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. using namespace System.IO; [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Scope = 'Function', Target = "Wrap-*")] Param() if ($PSVersionTable.PSVersion.Major -lt 6) { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', $null, Scope = 'Function')] $IsWindows = $true } if ($IsWindows) { $wslPath = "$env:windir\system32\wsl.exe" if (-not [System.Environment]::Is64BitProcess) { # Allow launching WSL from 32 bit powershell $wslPath = "$env:windir\sysnative\wsl.exe" } } else { # If running inside WSL, rely on wsl.exe being in the path. $wslPath = "wsl.exe" } # Helper that will launch wsl.exe, correctly parsing its output encoding, and throwing an error # if it fails. function Wrap-Wsl { param( [Parameter(Mandatory = $true, Position = 0, ValueFromRemainingArguments)] [string[]]$Arguments ) $hasError = $false try { $oldOutputEncoding = [System.Console]::OutputEncoding [System.Console]::OutputEncoding = [System.Text.Encoding]::Unicode Write-Verbose "Piping wsl.exe with arguments: $($Arguments -join ' ')" $output = &$wslPath @Arguments if ($LASTEXITCODE -ne 0) { throw [WslManagerException]::new("wsl.exe failed: $output") $hasError = $true } } finally { [System.Console]::OutputEncoding = $oldOutputEncoding } # $hasError is used so there's no output in case error action is silently continue. if (-not $hasError) { return $output } } function Wrap-Wsl-Raw { param( [Parameter(Mandatory = $true, Position = 0, ValueFromRemainingArguments)] [string[]]$Arguments ) Write-Verbose "Running wsl.exe with arguments: $($Arguments -join ' ')" &$wslPath $Arguments } # This one is here in order to perform unit test mocking function Get-WslRegistryBaseKey() { return [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey([WslInstance]::BaseInstancesRegistryPath, $true) } function Get-WslRegistryKey([string]$DistroName) { $baseKey = $null try { $baseKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey([WslInstance]::BaseInstancesRegistryPath, $true) return $baseKey.GetSubKeyNames() | Where-Object { $subKey = $baseKey.OpenSubKey($_, $false) try { $subKey.GetValue('DistributionName') -eq $DistroName } finally { if ($null -ne $subKey) { $subKey.Close() } } } | ForEach-Object { return $baseKey.OpenSubKey($_, $true) } } finally { if ($null -ne $baseKey) { $baseKey.Close() } } } # Helper to parse the output of wsl.exe --list function Get-WslHelper() { Wrap-Wsl --list --verbose | Select-Object -Skip 1 | ForEach-Object { $fields = $_.Split(@(" "), [System.StringSplitOptions]::RemoveEmptyEntries) $defaultDistro = $false if ($fields.Count -eq 4) { $defaultDistro = $true $fields = $fields | Select-Object -Skip 1 } [WslInstance]@{ Name = $fields[0] State = $fields[1] Version = [int]$fields[2] Default = $defaultDistro } } } |