diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 index 5e050e7..dafd8de 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Backup-FormtracepakSettings.ps1 @@ -84,6 +84,9 @@ $ErrorActionPreference = 'Continue' # ---------------------------------------------------------------------- $ApplicationPaths = @( + # v6.213 vendor MSI layout (the path the per-bay install lands on today). + "${env:ProgramFiles(x86)}\MitutoyoApp" + "${env:ProgramFiles}\MitutoyoApp" "${env:ProgramFiles}\Mitutoyo" "${env:ProgramFiles(x86)}\Mitutoyo" "${env:ProgramFiles}\FORMTRACEPAK" @@ -280,15 +283,28 @@ foreach ($root in $RegistryRoots) { Write-Warning " reg.exe export failed for ${root}: $_" } - # Also capture as CSV for granular restore + # Also capture as CSV for granular restore. + # + # CSV path only round-trips cleanly for String / ExpandString / DWord / + # QWord. Binary and MultiString lossily coerce through [string] (Binary + # becomes "System.Byte[]" literal; MultiString becomes space-joined), + # which then corrupts the registry if the CSV restore overwrites the + # .reg-import result. Skip those types in the CSV (the .reg file is + # authoritative for them). + $csvSafeTypes = @('String', 'ExpandString', 'DWord', 'QWord') try { $allKeys = @(Get-Item -Path $root -ErrorAction SilentlyContinue) $allKeys += Get-ChildItem -Path $root -Recurse -ErrorAction SilentlyContinue foreach ($key in $allKeys) { foreach ($valName in $key.GetValueNames()) { - $val = $key.GetValue($valName) $kind = $key.GetValueKind($valName) + if ($csvSafeTypes -notcontains [string]$kind) { + # Skip Binary / MultiString / None / Unknown. The .reg + # export already captured them losslessly. + continue + } + $val = $key.GetValue($valName) $regCsvRows.Add([PSCustomObject]@{ Path = $key.PSPath Name = $valName diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 index d5ce56a..5bd53f1 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Export-FormtracepakInventory.ps1 @@ -34,6 +34,9 @@ $ErrorActionPreference = 'Continue' # ---------------------------------------------------------------------- $ApplicationSearchPaths = @( + # v6.213 vendor MSI layout (the path the per-bay install lands on today). + "${env:ProgramFiles(x86)}\MitutoyoApp" + "${env:ProgramFiles}\MitutoyoApp" "${env:ProgramFiles}\Mitutoyo" "${env:ProgramFiles(x86)}\Mitutoyo" "${env:ProgramFiles}\FORMTRACEPAK" diff --git a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 index 6423a20..ca1d0d0 100755 --- a/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-waxtrace/scripts/Install-FormtracepakSettings.ps1 @@ -91,6 +91,11 @@ $ErrorActionPreference = 'Continue' # ---------------------------------------------------------------------- $DefaultAppTargets = [ordered]@{ + # v6.213 vendor MSI installs under MitutoyoApp\Formtracepak\. Order this + # first so restored config under e.g. C:\Mitutoyo\Formtracepak\ from an + # older bay lands in the right tree on a freshly imaged v6.213 bay. + 'MitutoyoAppX86' = "${env:ProgramFiles(x86)}\MitutoyoApp" + 'MitutoyoApp' = "${env:ProgramFiles}\MitutoyoApp" 'ProgramFiles' = "${env:ProgramFiles}\Mitutoyo" 'ProgramFilesX86' = "${env:ProgramFiles(x86)}\Mitutoyo" 'CMitutoyo' = 'C:\Mitutoyo' @@ -347,7 +352,13 @@ if ($RestoreRegistry) { $counters.RegistryKeys++ } - # Method 2: CSV-based key-by-key restore + # Method 2: CSV-based key-by-key restore. CSV captures String / + # ExpandString / DWord / QWord only (Backup-FormtracepakSettings.ps1 + # skips Binary + MultiString because [string] coercion corrupts them). + # The .reg file import above is authoritative for those types. Defend + # against older CSVs (pre-fix) that carry corrupt Binary/MultiString + # rows by skipping anything that is not a CSV-safe type. + $csvSafeTypes = @('String', 'ExpandString', 'DWord', 'QWord') $regCsv = Join-Path $regDir 'registry_values.csv' if (Test-Path $regCsv) { $regEntries = Import-Csv $regCsv @@ -357,6 +368,12 @@ if ($RestoreRegistry) { $regValue = $re.Value $regType = $re.Type + if ($regType -and ($csvSafeTypes -notcontains $regType)) { + Write-Host " [SKIP] Non-CSV-safe type '$regType' at ${regPath}\$regName (the .reg file import handled it)" -ForegroundColor DarkGray + $counters.Skipped++ + continue + } + if ($regPath -match '^HKLM' -and -not $isAdmin -and -not $DryRun) { Write-Host " [SKIP] HKLM key requires elevation: $regPath\$regName" -ForegroundColor DarkYellow $counters.Skipped++