119 lines
3.9 KiB
PowerShell
119 lines
3.9 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
将 Windows .reg 文件转换为 win-softmgr 所需的 post_install JSON 格式。
|
||
.EXAMPLE
|
||
.\convert-reg.ps1 -Path .\adobe.reg
|
||
#>
|
||
|
||
param (
|
||
[Parameter(Mandatory=$true)]
|
||
[string]$Path,
|
||
|
||
[Parameter(Mandatory=$false)]
|
||
[string]$OutputPath
|
||
)
|
||
|
||
if (-not (Test-Path $Path)) {
|
||
Write-Error "文件不存在: $Path"
|
||
exit 1
|
||
}
|
||
|
||
if ([string]::IsNullOrWhiteSpace($OutputPath)) {
|
||
$fileInfo = Get-Item $Path
|
||
$OutputPath = Join-Path $fileInfo.DirectoryName ($fileInfo.BaseName + ".json")
|
||
}
|
||
|
||
# 使用 -Raw 读取并自动检测编码,然后按行拆分
|
||
$content = Get-Content $Path -Raw
|
||
$lines = $content -split "\r?\n"
|
||
|
||
$results = @()
|
||
$currentBatch = $null
|
||
|
||
foreach ($line in $lines) {
|
||
$line = $line.Trim()
|
||
if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith("Windows Registry Editor")) {
|
||
continue
|
||
}
|
||
|
||
# 匹配 [HKEY_...] 路径
|
||
if ($line.StartsWith("[") -and $line.EndsWith("]")) {
|
||
# 检查是否是删除整个 Key 的语法:[-HKEY_...]
|
||
$isDeleteKey = $line.StartsWith("[-")
|
||
$fullPath = if ($isDeleteKey) { $line.Substring(2, $line.Length - 3) } else { $line.Substring(1, $line.Length - 2) }
|
||
|
||
$root = ""
|
||
$basePath = ""
|
||
|
||
if ($fullPath -match "^HKEY_CURRENT_USER(\\.*)?$") {
|
||
$root = "HKCU"
|
||
$basePath = if ($fullPath.Length -gt 17) { $fullPath.Substring(18) } else { "" }
|
||
} elseif ($fullPath -match "^HKEY_LOCAL_MACHINE(\\.*)?$") {
|
||
$root = "HKLM"
|
||
$basePath = if ($fullPath.Length -gt 18) { $fullPath.Substring(19) } else { "" }
|
||
}
|
||
|
||
if ($root -ne "") {
|
||
$currentBatch = [ordered]@{
|
||
type = "registry_batch"
|
||
root = $root
|
||
base_path = $basePath
|
||
# 如果是删除整个 Key,我们可以在这里记录或者扩展 schema
|
||
# 但目前我们先处理 Value 删除
|
||
values = [ordered]@{}
|
||
}
|
||
$results += $currentBatch
|
||
}
|
||
continue
|
||
}
|
||
|
||
# 匹配 "Name"=Value
|
||
if ($line -match '^"(.+)"\s*=\s*(.+)$') {
|
||
$name = $Matches[1]
|
||
$rawVal = $Matches[2]
|
||
$vType = ""
|
||
$data = $null
|
||
|
||
if ($rawVal -eq "-") {
|
||
# 处理删除 Value 的逻辑: "Key"=-
|
||
$vType = "Delete"
|
||
$data = $null
|
||
} elseif ($rawVal.StartsWith("dword:")) {
|
||
$vType = "Dword"
|
||
$hex = $rawVal.Substring(6)
|
||
$data = [Convert]::ToInt32($hex, 16)
|
||
} elseif ($rawVal.StartsWith('"') -and $rawVal.EndsWith('"')) {
|
||
$vType = "String"
|
||
$data = $rawVal.Substring(1, $rawVal.Length - 2).Replace("\\", "\")
|
||
} elseif ($rawVal.StartsWith("hex(7):")) {
|
||
$vType = "MultiString"
|
||
$hexBytes = $rawVal.Substring(7).Split(',') | ForEach-Object { [Convert]::ToByte($_, 16) }
|
||
$decoded = [System.Text.Encoding]::Unicode.GetString($hexBytes)
|
||
$data = $decoded.Split("`0", [System.StringSplitOptions]::RemoveEmptyEntries)
|
||
} elseif ($rawVal.StartsWith("hex(b):")) {
|
||
$vType = "Qword"
|
||
$hexBytes = $rawVal.Substring(7).Split(',') | ForEach-Object { $_ }
|
||
if ($hexBytes.Count -ge 8) {
|
||
$hexStr = ($hexBytes[7,6,5,4,3,2,1,0] -join "")
|
||
$data = [Convert]::ToInt64($hexStr, 16)
|
||
}
|
||
}
|
||
|
||
if ($null -ne $currentBatch -and $vType -ne "") {
|
||
$currentBatch.values[$name] = [ordered]@{
|
||
v_type = $vType
|
||
data = $data
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ($results.Count -eq 0) {
|
||
Write-Warning "未在文件中识别到有效的注册表项。"
|
||
}
|
||
|
||
$jsonOutput = ConvertTo-Json $results -Depth 10
|
||
[System.IO.File]::WriteAllText($OutputPath, $jsonOutput, [System.Text.Encoding]::UTF8)
|
||
|
||
Write-Host "转换成功!结果已保存至: $OutputPath" -ForegroundColor Green
|