# kb_pointer_refresh_v1.0.ps1 — Recompute & rewrite pointer (UTF-8 no BOM, CRLF) Param( [Parameter(Mandatory=$true)][string]$RegistryRoot, [switch]$Write ) try { [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false) } catch {} function Read-Text([string]$p){ if(-not (Test-Path -LiteralPath $p)){ return '' } try { return Get-Content -LiteralPath $p -Raw -Encoding UTF8 } catch { return (Get-Content -LiteralPath $p -Raw) } } function Count-EntriesFromJson([string]$json){ if([string]::IsNullOrWhiteSpace($json)){ return -1 } if($json.Length -gt 0 -and ([int]$json[0] -eq 0xFEFF)){ $json = $json.Substring(1) } try{ $o = $json | ConvertFrom-Json if($null -ne $o -and $o.PSObject.Properties.Name -contains 'entries'){ return @($o.entries).Count } }catch{} try{ $m = [regex]::Match($json,'(?ms)"entries"\s*:\s*\[(.*?)\]') if($m.Success){ return ([regex]::Matches($m.Groups[1].Value,'(?i)"id"\s*:')).Count } }catch{} return -1 } $bp = Join-Path $RegistryRoot 'bootpack\bootpack.txt' if(-not (Test-Path -LiteralPath $bp)){ Write-Host "[ERROR] bootpack.txt introuvable -> $bp"; exit 2 } $rawBP = Read-Text $bp # 1) Récupère le chemin du paste depuis la ligne "KB Pointer :" ou le bloc pointer $pp = '' $m = [regex]::Match($rawBP,'(?mi)^\s*KB\W*Pointer\s*:\s*(.+?)\s*(?:\(|$)') if($m.Success){ $pp = $m.Groups[1].Value.Trim() } if([string]::IsNullOrWhiteSpace($pp)){ $m = [regex]::Match($rawBP,'(?ms)^\[BUG_KB_JSON_POINTER\][\s\S]*?^\s*Path\s*:\s*(.+?)\s*$', [System.Text.RegularExpressions.RegexOptions]::Multiline) if($m.Success){ $pp = $m.Groups[1].Value.Trim() } } if([string]::IsNullOrWhiteSpace($pp) -or -not (Test-Path -LiteralPath $pp)){ Write-Host "[ERROR] pointer path not found/invalid."; exit 2 } $rawPaste = Read-Text $pp $sha = (Get-FileHash -Algorithm SHA256 -LiteralPath $pp).Hash.ToUpperInvariant() $size = (Get-Item -LiteralPath $pp).Length $ents = Count-EntriesFromJson $rawPaste # 2) Construit le bloc canonical + la ligne $block = @" [BUG_KB_JSON_POINTER] Path : $pp SHA256 : $sha Entries : $ents SizeBytes : $size "@.Trim()+"`r`n" $linePtr = "KB Pointer : $pp (SHA=$sha, Entries=$ents, Size=$size)" # 3) Remplacement (ou insertion) du bloc + synchro de la ligne $rawOut = $rawBP $patBlock = '(?ms)^\[BUG_KB_JSON_POINTER\][\s\S]*?(?=^\[|\z)' if([regex]::IsMatch($rawOut,$patBlock)){ $rawOut = [regex]::Replace($rawOut,$patBlock,$block) }else{ $rawOut = $block + "`r`n" + $rawOut } $patLine = '(?mi)^\s*KB\W*Pointer\s*:\s*.*$' if([regex]::IsMatch($rawOut,$patLine)){ $rawOut = [regex]::Replace($rawOut,$patLine,$linePtr,1) }else{ $rawOut = $block + $linePtr + "`r`n`r`n" + [regex]::Replace($rawOut,$patBlock,'') } # 4) Écriture sûre Write-Host "[POINTER] Path=$pp" Write-Host ("Values : SHA={0} Entries={1} Size={2}" -f $sha,$ents,$size) if($Write){ $bak = $bp + '.bak_' + (Get-Date -Format 'yyyyMMdd_HHmmss') Copy-Item -LiteralPath $bp -Destination $bak -Force $out = ($rawOut -replace '(\r?\n)',"`r`n") $enc = New-Object System.Text.UTF8Encoding($false) [IO.File]::WriteAllText($bp,$out,$enc) Write-Host "STATUS=WRITE-OK -> $bp" Write-Host "Backup -> $bak" }else{ Write-Host "PREVIEW (no write)." }