fix: 让 5.1 真正可用(显式编码 + 原生 stderr 处理 + .psd1 夹具带 BOM)

上一提交让 5.1 能解析源码,但 Unit 与 Smoke 在 5.1 上仍然是红的。根因是三类彼此
无关的 5.1/7 行为差,全部实测确认:

1) 不写 -Encoding 时,5.1 的 Get-Content / Set-Content 默认是 ANSI,7 是 UTF-8。
   症状是 UTF-8 字节被按 GBK 解出「璇存槑」这类乱码。62 处补上显式 -Encoding UTF8。
   用 AST 而不是正则定位,避免把注释里的散文也改掉。

2) .psd1 夹具用无 BOM 写,而引擎的 .psd1 读取器(Import-PowerShellDataFile)只能靠
   BOM 判断编码、没有参数可传,于是 5.1 按 ANSI 解。40 处夹具改为带 BOM 写 —— 这正是
   .editorconfig 里 [*.psd1] charset = utf-8-bom 本来就要求的,是夹具违反了自己的约定。
   .cmd 批次文件刻意保持无 BOM:cmd.exe 会被 BOM 弄坏。

3) 5.1 在 $ErrorActionPreference = Stop 下会把原生命令写到 stderr 的内容升级成终止性
   NativeCommandError,7 改了这条。takeown/icacls 的 ACL 复位调用、以及 test.ps1 自己
   调子进程的地方,都需要在 Continue 下跑。

验收:test.ps1 9/9 全绿(Encode + Parse + Unit + Smoke + E2E,在 7 与 5.1 上各跑一遍)。

已知未处理(留待后续提交):tools/lab/** 里还有若干「原生命令 + 2>&1 + Stop」的同类
写法(takeown / icacls / scoop / code / Get-WimInfo)。它们要 Hyper-V 实验机才跑得到,
不在验收门槛内。
This commit is contained in:
Shuery committed 2026-09-26 22:16:04 +08:00
1 parent 2d26f78d15
commit e10503be76
13 files changed
+122 -104

No files matched your search

+1 -1
View File
@@ -117,7 +117,7 @@ $conflicts = @()
$seenNew = @{}
$entries = @()
foreach ($line in (Get-Content -LiteralPath $BackupListPath)) {
foreach ($line in (Get-Content -Encoding UTF8 -LiteralPath $BackupListPath)) {
$item = ConvertFrom-BackupListLine -Line $line
if (-not $item) { continue }
+1 -1
View File
@@ -267,7 +267,7 @@ switch ($Verb) {
while ($sw.Elapsed.TotalMinutes -lt 30) {
if (Test-LabGuestReady) {
Write-LabLog ("VM 已就绪(等待 {0} 分钟)" -f [math]::Round($sw.Elapsed.TotalMinutes, 1)) 'STEP'
$facts = Invoke-LabCommand -ScriptBlock { Get-Content 'C:\BakNRet-Lab\state\provisioned.json' -Raw }
$facts = Invoke-LabCommand -ScriptBlock { Get-Content -Encoding UTF8 'C:\BakNRet-Lab\state\provisioned.json' -Raw }
Write-Host $facts
break
}
+1 -1
View File
@@ -224,7 +224,7 @@ function Wait-LabProvision {
while ($sw.Elapsed.TotalMinutes -lt 30) {
if (Test-LabGuestReady) {
Write-LabLog "供给完成,耗时 $([math]::Round($sw.Elapsed.TotalMinutes,1)) 分钟" 'STEP'
$facts = Invoke-LabCommand -ScriptBlock { Get-Content 'C:\BakNRet-Lab\state\provisioned.json' -Raw }
$facts = Invoke-LabCommand -ScriptBlock { Get-Content -Encoding UTF8 'C:\BakNRet-Lab\state\provisioned.json' -Raw }
Write-Host $facts
return
}
+3 -3
View File
@@ -340,7 +340,7 @@ $listPath = Join-Path $WorkRoot 'BackupList.txt'
$entries = @()
if ($vscodeReady) { $entries += $vscodeApp; $entries += $vscodePersist }
$entries += $bData
[System.IO.File]::WriteAllText($listPath, (($entries -join [Environment]::NewLine) + [Environment]::NewLine), [System.Text.UTF8Encoding]::new($false))
[System.IO.File]::WriteAllText($listPath, (($entries -join [Environment]::NewLine) + [Environment]::NewLine), [System.Text.UTF8Encoding]::new($true))
$configPath = Join-Path $WorkRoot 'BackupConfig.psd1'
$configText = @"
@@ -359,7 +359,7 @@ $configText = @"
DefaultExcludes = @('!Thumbs.db', '!desktop.ini')
}
"@
[System.IO.File]::WriteAllText($configPath, $configText, [System.Text.UTF8Encoding]::new($false))
[System.IO.File]::WriteAllText($configPath, $configText, [System.Text.UTF8Encoding]::new($true))
Write-Host ''
Write-Host '[备份] Backup.ps1' -ForegroundColor Yellow
@@ -406,7 +406,7 @@ if ($vscodeReady) {
$settingsOk = $false
if ($settingsPath -and (Test-Path -LiteralPath $settingsPath)) {
$settingsOk = (Get-Content -LiteralPath $settingsPath -Raw) -match [regex]::Escape($probe)
$settingsOk = (Get-Content -Encoding UTF8 -LiteralPath $settingsPath -Raw) -match [regex]::Escape($probe)
}
Test-Scenario 'A: 改过的 settings.json 被原样恢复(读得到、内容对)' $settingsOk $settingsPath