|
1 | | -# Load YamlDotNet for YAML parsing |
2 | | -# YamlDotNet by Antoine Aubry - https://github.com/aaubry/YamlDotNet (MIT License) |
3 | | -Add-Type -Path "$PSScriptRoot\YamlDotNet.dll" |
| 1 | +$configurationFolder = Join-Path $PSScriptRoot "..\Configuration\tweaks" |
| 2 | +$yamlFiles = Get-ChildItem -Path $configurationFolder -Filter *.yml -Recurse -File |
4 | 3 |
|
5 | | -function ConvertFrom-Yaml { |
6 | | - param([string]$YamlString) |
7 | | - $reader = New-Object System.IO.StringReader($YamlString) |
8 | | - $yamlStream = New-Object YamlDotNet.RepresentationModel.YamlStream |
9 | | - $yamlStream.Load($reader) |
10 | | - $reader.Close() |
| 4 | +$registryPaths = New-Object System.Collections.Generic.HashSet[string]([System.StringComparer]::OrdinalIgnoreCase) |
| 5 | +$pathPattern = [regex]::new('^(?!\s*#).*?\bpath\s*:\s*[''\"]HKCU\\(?<path>[^''\"]+)[''\"]', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline) |
11 | 6 |
|
12 | | - function ConvertNode($node) { |
13 | | - if ($node -is [YamlDotNet.RepresentationModel.YamlMappingNode]) { |
14 | | - $ht = @{} |
15 | | - foreach ($pair in $node.Children) { |
16 | | - $ht[$pair.Key.Value] = ConvertNode $pair.Value |
17 | | - } |
18 | | - return $ht |
19 | | - } |
20 | | - elseif ($node -is [YamlDotNet.RepresentationModel.YamlSequenceNode]) { |
21 | | - $arr = @() |
22 | | - foreach ($item in $node.Children) { |
23 | | - $arr += ConvertNode $item |
24 | | - } |
25 | | - return $arr |
26 | | - } |
27 | | - else { |
28 | | - return $node.Value |
| 7 | +foreach ($yamlFile in $yamlFiles) { |
| 8 | + $yamlContent = Get-Content -Path $yamlFile.FullName -Raw |
| 9 | + foreach ($match in $pathPattern.Matches($yamlContent)) { |
| 10 | + $relativePath = $match.Groups['path'].Value.Trim() |
| 11 | + if (![string]::IsNullOrWhiteSpace($relativePath)) { |
| 12 | + $null = $registryPaths.Add($relativePath) |
29 | 13 | } |
30 | 14 | } |
| 15 | +} |
31 | 16 |
|
32 | | - return ConvertNode $yamlStream.Documents[0].RootNode |
| 17 | +if ($registryPaths.Count -eq 0) { |
| 18 | + Write-Warning "No HKCU registry paths were found in tweak YAML files." |
| 19 | + exit |
33 | 20 | } |
34 | 21 |
|
35 | | -$configurationFolder = Join-Path $PSScriptRoot "..\Configuration\tweaks" |
36 | | -$yamlFiles = Get-ChildItem -Path $configurationFolder -Filter *.yml -Recurse |
37 | | -$RegistryPaths = @() |
38 | | -foreach ($yamlFile in $yamlFiles) { |
39 | | - $yamlContent = Get-Content $yamlFile.FullName -Raw |
40 | | - $parsedYaml = ConvertFrom-Yaml $yamlContent |
41 | | - foreach ($entry in $parsedYaml) { |
42 | | - foreach ($value in $entry.actions.path) { |
43 | | - if ($value -like 'HKCU') { |
44 | | - if (!$RegistryPaths.Contains($value.Substring(4))) { $RegistryPaths += $value.Substring(4) } |
45 | | - } |
| 22 | +foreach ($relativePath in ($registryPaths | Sort-Object)) { |
| 23 | + $sourceKey = $null |
| 24 | + $destinationKey = $null |
| 25 | + |
| 26 | + try { |
| 27 | + $sourceKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($relativePath, $false) |
| 28 | + if ($null -eq $sourceKey) { |
| 29 | + continue |
| 30 | + } |
| 31 | + |
| 32 | + $destinationKey = [Microsoft.Win32.Registry]::Users.CreateSubKey("AME_UserHive_Default\$relativePath") |
| 33 | + if ($null -eq $destinationKey) { |
| 34 | + Write-Warning "Failed to create destination key: HKU\\AME_UserHive_Default\\$relativePath" |
| 35 | + continue |
46 | 36 | } |
47 | | - } |
48 | | -} |
49 | 37 |
|
50 | | -foreach ($path in $RegistryPaths) { |
51 | | - $source = "Registry::HKCU\$path" |
52 | | - $destination = "Registry::HKU\AME_UserHive_Default\$path" |
53 | | - $values = Get-ItemProperty -Path $source -ErrorAction SilentlyContinue |
54 | | - if ($values) { |
55 | | - foreach ($property in $values.PSObject.Properties) { |
56 | | - if ($property.Name -ne "PSPath" -and $property.Name -ne "PSParentPath" -and $property.Name -ne "PSChildName" -and $property.Name -ne "PSDrive" -and $property.Name -ne "PSProvider") { |
57 | | - if (-not (Test-Path $destination)) { |
58 | | - New-Item -Path $destination -Force | Out-Null |
59 | | - } |
60 | | - if (-not ((Get-ItemProperty $destination -ErrorAction SilentlyContinue).PSObject.Properties.Name -contains $property.Name)) { |
61 | | - New-ItemProperty -Path $destination -Name $property.Name -Value $property.Value | Out-Null |
62 | | - } |
63 | | - else { |
64 | | - Set-ItemProperty -Path $destination -Name $property.Name -Value $property.Value |
65 | | - } |
66 | | - } |
| 38 | + foreach ($valueName in $sourceKey.GetValueNames()) { |
| 39 | + $value = $sourceKey.GetValue($valueName, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) |
| 40 | + $kind = $sourceKey.GetValueKind($valueName) |
| 41 | + $destinationKey.SetValue($valueName, $value, $kind) |
| 42 | + } |
| 43 | + } |
| 44 | + finally { |
| 45 | + if ($null -ne $destinationKey) { |
| 46 | + $destinationKey.Close() |
| 47 | + } |
| 48 | + if ($null -ne $sourceKey) { |
| 49 | + $sourceKey.Close() |
67 | 50 | } |
68 | 51 | } |
69 | 52 | } |
0 commit comments