mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-10-17 03:02:04 +00:00
Add localization framework for the GUI (en-US baseline) (#764)
Credit to @jmolinap2 for their work in #643, which was used as inspiration.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Extracts and deduplicates the SelectedFeatures list from a backup, validating each entry.
|
||||
|
||||
.DESCRIPTION
|
||||
Returns an empty SelectedFeatures array with an error when the property is missing
|
||||
entirely, and flags (without stopping) any entry that isn't a non-empty string.
|
||||
#>
|
||||
function Get-NormalizedSelectedFeatureIdsFromBackup {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -10,7 +18,7 @@ function Get-NormalizedSelectedFeatureIdsFromBackup {
|
||||
$hasInvalidSelectedFeatureId = $false
|
||||
|
||||
if (-not $Backup.PSObject.Properties['SelectedFeatures']) {
|
||||
$errors.Add('Missing property: SelectedFeatures')
|
||||
$errors.Add((Get-Translation -Key 'BackupMissingProperty' -FormatArgs @('SelectedFeatures')))
|
||||
return [PSCustomObject]@{
|
||||
SelectedFeatures = $selectedFeatures.ToArray()
|
||||
Errors = $errors.ToArray()
|
||||
@@ -30,7 +38,7 @@ function Get-NormalizedSelectedFeatureIdsFromBackup {
|
||||
}
|
||||
|
||||
if ($hasInvalidSelectedFeatureId) {
|
||||
$errors.Add('SelectedFeatures must contain non-empty string feature IDs.')
|
||||
$errors.Add((Get-Translation -Key 'BackupSelectedFeaturesMustBeStrings'))
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
@@ -39,6 +47,14 @@ function Get-NormalizedSelectedFeatureIdsFromBackup {
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Extracts and deduplicates the SelectedUndoFeatures list from a backup, validating each entry.
|
||||
|
||||
.DESCRIPTION
|
||||
Unlike SelectedFeatures, this property is optional: a missing property returns an
|
||||
empty array with no error, since not every backup has undone features to restore.
|
||||
#>
|
||||
function Get-NormalizedSelectedUndoFeatureIdsFromBackup {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -71,7 +87,7 @@ function Get-NormalizedSelectedUndoFeatureIdsFromBackup {
|
||||
}
|
||||
|
||||
if ($hasInvalidSelectedUndoFeatureId) {
|
||||
$errors.Add('SelectedUndoFeatures must contain non-empty string feature IDs.')
|
||||
$errors.Add((Get-Translation -Key 'BackupSelectedUndoFeaturesMustBeStrings'))
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
@@ -80,6 +96,15 @@ function Get-NormalizedSelectedUndoFeatureIdsFromBackup {
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Normalizes a raw registry key snapshot into a consistent shape, recursing into sub-keys.
|
||||
|
||||
.DESCRIPTION
|
||||
Fills in defaults for optional properties (Exists, Values, SubKeys) so downstream
|
||||
validation can read a predictable shape regardless of what the backup file omitted.
|
||||
Throws if Path is missing, since every snapshot must be anchored to a real key.
|
||||
#>
|
||||
function Normalize-RegistryKeySnapshot {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -87,7 +112,7 @@ function Normalize-RegistryKeySnapshot {
|
||||
)
|
||||
|
||||
if (-not $Snapshot.PSObject.Properties['Path'] -or [string]::IsNullOrWhiteSpace([string]$Snapshot.Path)) {
|
||||
throw 'Backup validation failed: Registry key snapshot is missing Path.'
|
||||
throw (Get-Translation -Key 'BackupSnapshotMissingPath')
|
||||
}
|
||||
|
||||
$exists = $false
|
||||
@@ -127,6 +152,16 @@ function Normalize-RegistryKeySnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Validates that a backup's registry snapshots only contain paths and values the
|
||||
selected (and undo) features are actually allowed to touch.
|
||||
|
||||
.DESCRIPTION
|
||||
Builds an allow-list from the capture plans of the selected features, then checks
|
||||
every snapshot against it. Returns an array of translated error strings; an empty
|
||||
array means the backup is valid.
|
||||
#>
|
||||
function Test-RegistryBackupMatchesSelectedFeatures {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -145,7 +180,7 @@ function Test-RegistryBackupMatchesSelectedFeatures {
|
||||
$errors = New-Object System.Collections.Generic.List[string]
|
||||
|
||||
if (-not $script:Features -or $script:Features.Count -eq 0) {
|
||||
$errors.Add('Unable to validate registry backup allowlist because feature definitions are not loaded.')
|
||||
$errors.Add((Get-Translation -Key 'BackupFeatureCatalogNotLoaded'))
|
||||
return $errors.ToArray()
|
||||
}
|
||||
|
||||
@@ -161,7 +196,7 @@ function Test-RegistryBackupMatchesSelectedFeatures {
|
||||
$planMap = New-RegistryBackupAllowListPlanMap -CapturePlans @($capturePlans)
|
||||
|
||||
if ($planMap.Count -eq 0 -and @($RegistryKeys).Count -gt 0) {
|
||||
$errors.Add('Backup contains registry snapshots but no allowed registry paths were derived from the selected features.')
|
||||
$errors.Add((Get-Translation -Key 'BackupNoAllowedRegistryPaths'))
|
||||
}
|
||||
|
||||
foreach ($rootSnapshot in @($RegistryKeys)) {
|
||||
@@ -171,6 +206,15 @@ function Test-RegistryBackupMatchesSelectedFeatures {
|
||||
return $errors.ToArray()
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Resolves selected feature IDs to their catalog entries, keeping only the ones with a
|
||||
registry-backed apply or undo key relevant to the requested direction.
|
||||
|
||||
.DESCRIPTION
|
||||
Appends a translated error to the caller-supplied Errors list for any feature ID that
|
||||
isn't in the current catalog, rather than failing the whole validation outright.
|
||||
#>
|
||||
function Get-SelectedRegistryFeaturesForBackupValidation {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -186,11 +230,13 @@ function Get-SelectedRegistryFeaturesForBackupValidation {
|
||||
if ($null -eq $Errors -or -not ($Errors -is [System.Collections.IList])) {
|
||||
throw 'Get-SelectedRegistryFeaturesForBackupValidation requires Errors to be a mutable list collection.'
|
||||
}
|
||||
# Intentionally not localized: this throw signals a programming error (a caller passing the
|
||||
# wrong collection type), not a condition a user's backup file can trigger.
|
||||
|
||||
$selectedRegistryFeatures = New-Object System.Collections.Generic.List[object]
|
||||
foreach ($featureId in @($SelectedFeatureIds)) {
|
||||
if (-not $script:Features.ContainsKey($featureId)) {
|
||||
$Errors.Add("Selected feature '$featureId' was not found in the current feature catalog.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupFeatureNotInCatalog' -FormatArgs @($featureId)))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -293,13 +339,13 @@ function Test-RegistrySnapshotAgainstAllowList {
|
||||
$snapshotPath = [string]$Snapshot.Path
|
||||
$normalizedPath = Get-NormalizedRegistryPathKey -Path $snapshotPath
|
||||
if ([string]::IsNullOrWhiteSpace($normalizedPath)) {
|
||||
$Errors.Add("Backup contains unsupported registry path '$snapshotPath'.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupUnsupportedRegistryPath' -FormatArgs @($snapshotPath)))
|
||||
return
|
||||
}
|
||||
|
||||
$planMatch = Find-RegistryAllowListPlanMatch -NormalizedPath $normalizedPath -PlanMap $PlanMap
|
||||
if ($null -eq $planMatch) {
|
||||
$Errors.Add("Backup contains unexpected registry path '$snapshotPath' that is not allowed by SelectedFeatures.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupUnexpectedRegistryPath' -FormatArgs @($snapshotPath)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -308,21 +354,21 @@ function Test-RegistrySnapshotAgainstAllowList {
|
||||
$valueExists = [bool]$valueSnapshot.Exists
|
||||
|
||||
if (-not (Test-RegistryValueAllowedByPlan -PlanMatch $planMatch -ValueName $valueName)) {
|
||||
$Errors.Add("Backup contains unexpected value '$valueName' under '$snapshotPath'.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupUnexpectedValue' -FormatArgs @($valueName, $snapshotPath)))
|
||||
}
|
||||
|
||||
$kindName = if ($valueSnapshot.PSObject.Properties['Kind']) { [string]$valueSnapshot.Kind } else { '' }
|
||||
$valueReference = Get-RegistryValueReferenceForError -SnapshotPath $snapshotPath -ValueName $valueName
|
||||
if ($valueExists) {
|
||||
if (-not (Test-RegistryValueKindNameSupported -KindName $kindName)) {
|
||||
$Errors.Add("Backup contains unsupported registry value kind '$kindName' for '$valueReference'.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupUnsupportedValueKind' -FormatArgs @($kindName, $valueReference)))
|
||||
}
|
||||
elseif (-not (Test-RegistryValueDataMatchesKind -KindName $kindName -Data $valueSnapshot.Data)) {
|
||||
$Errors.Add("Backup contains invalid registry data for kind '$kindName' at '$valueReference'.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupInvalidValueData' -FormatArgs @($kindName, $valueReference)))
|
||||
}
|
||||
}
|
||||
elseif (-not [string]::IsNullOrWhiteSpace($kindName)) {
|
||||
$Errors.Add("Backup value '$valueReference' must not define Kind when Exists is false.")
|
||||
$Errors.Add((Get-Translation -Key 'BackupValueMustNotDefineKind' -FormatArgs @($valueReference)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user