264 lines
12 KiB
PowerShell
264 lines
12 KiB
PowerShell
# ===========================================================================
|
||
# 成套报价 CAD 插件 - 通用卸载脚本
|
||
# 自动检测 AutoCAD 并移除所有安装时写入的配置
|
||
# 用法:以管理员身份运行,或在 PowerShell 中执行本脚本
|
||
# ===========================================================================
|
||
|
||
# --- 0. 环境与自检 ---
|
||
$ErrorActionPreference = 'Stop'
|
||
# $PSScriptRoot 在 -File 模式下可靠返回脚本所在目录(PS 3.0+)
|
||
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }
|
||
$scriptDir = $scriptDir.TrimEnd('\') # 统一去除尾部反斜杠,便于比较
|
||
|
||
# 检测是否管理员(写 HKLM 需要)
|
||
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||
if (-not $isAdmin) {
|
||
Write-Host "[提示] 当前未以管理员身份运行,HKLM 注册表删除将自动提权。" -ForegroundColor Yellow
|
||
Write-Host " acaddoc.lsp 和 TRUSTEDPATHS 无需管理员权限。" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
}
|
||
|
||
Write-Host "======================================================" -ForegroundColor Cyan
|
||
Write-Host " 成套报价 CAD 插件卸载程序" -ForegroundColor Cyan
|
||
Write-Host " 插件目录: $scriptDir" -ForegroundColor Cyan
|
||
Write-Host "======================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# --- 1. 检测已安装的 AutoCAD 版本 ---
|
||
Write-Host "[1/4] 检测 AutoCAD 安装..." -ForegroundColor Green
|
||
|
||
$acadInstalls = @()
|
||
$regRoots = @(
|
||
'HKLM:\SOFTWARE\Autodesk\AutoCAD',
|
||
'HKLM:\SOFTWARE\WOW6432Node\Autodesk\AutoCAD'
|
||
)
|
||
|
||
foreach ($root in $regRoots) {
|
||
if (-not (Test-Path $root)) { continue }
|
||
Get-ChildItem $root -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -match '^R\d+\.0$' } | ForEach-Object {
|
||
$verKey = $_.PSPath
|
||
$verNum = $_.PSChildName
|
||
Get-ChildItem $verKey -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -match '^ACAD-\d+:\d+$' } | ForEach-Object {
|
||
$langKey = $_.PSPath
|
||
$props = Get-ItemProperty -Path $langKey -ErrorAction SilentlyContinue
|
||
$loc = $props.AcadLocation
|
||
$prod = $props.ProductName
|
||
if ($loc -and (Test-Path $loc)) {
|
||
$acadInstalls += [PSCustomObject]@{
|
||
Version = $verNum
|
||
LangKey = $_.PSChildName
|
||
Location = $loc
|
||
Product = $prod
|
||
HKLMKey = $langKey
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ($acadInstalls.Count -eq 0) {
|
||
Write-Host "[警告] 未检测到已安装的 AutoCAD,无法清理注册表。" -ForegroundColor Yellow
|
||
Write-Host " 如有手动残留的 acaddoc.lsp,请手动检查。" -ForegroundColor Yellow
|
||
if (-not $env:CADCJ_SILENT) { Read-Host "按回车退出" }
|
||
exit 0
|
||
}
|
||
|
||
Write-Host "找到 $($acadInstalls.Count) 个 AutoCAD 安装:" -ForegroundColor Green
|
||
for ($i = 0; $i -lt $acadInstalls.Count; $i++) {
|
||
$a = $acadInstalls[$i]
|
||
Write-Host (" [{0}] {1} ({2}) - {3}" -f $i, $a.Product, $a.Version, $a.Location) -ForegroundColor White
|
||
}
|
||
Write-Host ""
|
||
|
||
# 若有多个,让用户选择
|
||
$target = $acadInstalls[0]
|
||
if ($acadInstalls.Count -gt 1) {
|
||
if ($env:CADCJ_SILENT) {
|
||
Write-Host "[静默模式] 检测到多个 AutoCAD,默认选择第一个: $($target.Product)" -ForegroundColor Yellow
|
||
} else {
|
||
do {
|
||
$sel = Read-Host "请选择要卸载的 AutoCAD 序号 (0-$($acadInstalls.Count - 1)),默认 0"
|
||
if ([string]::IsNullOrWhiteSpace($sel)) { $sel = '0' }
|
||
} until ($sel -match '^\d+$' -and [int]$sel -lt $acadInstalls.Count)
|
||
$target = $acadInstalls[[int]$sel]
|
||
}
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host ("目标: {0} ({1})" -f $target.Product, $target.Version) -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# --- 2. 删除 HKLM 注册表 CADCJ 节点 ---
|
||
Write-Host "[2/4] 删除 HKLM 自动加载注册表..." -ForegroundColor Green
|
||
|
||
$hklmPath = $target.HKLMKey -replace '^HKLM:\\', ''
|
||
$appsPath = "HKLM:\$hklmPath\Apps\CADCJ"
|
||
|
||
if (-not (Test-Path $appsPath)) {
|
||
Write-Host " HKLM 中无 CADCJ 节点,跳过" -ForegroundColor DarkGray
|
||
} else {
|
||
if ($isAdmin) {
|
||
Remove-Item -Path $appsPath -Recurse -Force -ErrorAction SilentlyContinue
|
||
if (-not (Test-Path $appsPath)) {
|
||
Write-Host " 已删除 HKLM 注册表节点" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " [警告] 删除失败,请检查权限" -ForegroundColor Yellow
|
||
}
|
||
} else {
|
||
# 提权删除
|
||
$tmpPs1 = Join-Path $env:TEMP "cadcj_uninstall_hklm.ps1"
|
||
$tmpContent = @"
|
||
`$ErrorActionPreference = 'Stop'
|
||
`$path = '$appsPath'
|
||
if (Test-Path `$path) { Remove-Item -Path `$path -Recurse -Force }
|
||
if (-not (Test-Path `$path)) { Write-Host ' HKLM 注册表节点已删除' } else { Write-Host ' [警告] 删除失败' }
|
||
"@
|
||
$tmpContent | Out-File -FilePath $tmpPs1 -Encoding UTF8 -Force
|
||
$p = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile","-ExecutionPolicy","Bypass","-File",$tmpPs1 -Verb RunAs -Wait -PassThru
|
||
if ($p.ExitCode -eq 0) {
|
||
Write-Host " 已删除 HKLM 注册表节点" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " [警告] HKLM 删除失败(用户取消提权?)" -ForegroundColor Yellow
|
||
}
|
||
Remove-Item $tmpPs1 -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# --- 3. 从所有 TRUSTEDPATHS 移除插件目录 ---
|
||
Write-Host "[3/4] 移除受信任路径(TRUSTEDPATHS)..." -ForegroundColor Green
|
||
|
||
$hkcuRoot = "HKCU:\SOFTWARE\Autodesk\AutoCAD\$($target.Version)\$($target.LangKey)"
|
||
|
||
$targets = @()
|
||
$topVar = Join-Path $hkcuRoot 'Variables'
|
||
if (Test-Path $topVar) { $targets += $topVar }
|
||
$profRoot = Join-Path $hkcuRoot 'Profiles'
|
||
if (Test-Path $profRoot) {
|
||
Get-ChildItem $profRoot -ErrorAction SilentlyContinue | ForEach-Object {
|
||
$pv = Join-Path $_.PSPath 'Variables'
|
||
if (Test-Path $pv) { $targets += $pv }
|
||
}
|
||
}
|
||
|
||
$removedCount = 0
|
||
foreach ($t in $targets) {
|
||
$cur = (Get-ItemProperty -Path $t -Name 'TRUSTEDPATHS' -ErrorAction SilentlyContinue).TRUSTEDPATHS
|
||
if (-not $cur) { continue }
|
||
# 分割后去除每段首尾空白,统一比较
|
||
$allParts = $cur.Split(';') | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' }
|
||
$keepParts = $allParts | Where-Object { -not $_.Equals($scriptDir, [StringComparison]::OrdinalIgnoreCase) }
|
||
$hasOurs = ($allParts | Where-Object { $_.Equals($scriptDir, [StringComparison]::OrdinalIgnoreCase) }).Count -gt 0
|
||
$shortName = $t -replace '.*\\Profiles\\','Profile\' -replace '\\Variables',''
|
||
if (-not $hasOurs) {
|
||
Write-Host " 未包含: $shortName 跳过" -ForegroundColor DarkGray
|
||
continue
|
||
}
|
||
if ($keepParts.Count -eq 0) {
|
||
# 全部都是本目录,删除整个值
|
||
Remove-ItemProperty -Path $t -Name 'TRUSTEDPATHS' -ErrorAction SilentlyContinue
|
||
Write-Host " 已清空: $shortName" -ForegroundColor Green
|
||
} else {
|
||
$newVal = $keepParts -join ';'
|
||
Set-ItemProperty -Path $t -Name 'TRUSTEDPATHS' -Value $newVal -Type String -Force
|
||
Write-Host " 已移除: $shortName" -ForegroundColor Green
|
||
}
|
||
$removedCount++
|
||
}
|
||
if ($removedCount -eq 0) {
|
||
Write-Host " 无需修改(TRUSTEDPATHS 中未包含本目录)" -ForegroundColor DarkGray
|
||
}
|
||
Write-Host ""
|
||
|
||
# --- 4. 清理 acaddoc.lsp 中的 CADCJ 加载逻辑 ---
|
||
Write-Host "[4/4] 清理 acaddoc.lsp 自动加载脚本..." -ForegroundColor Green
|
||
|
||
$acadDirName = Split-Path $target.Location -Leaf
|
||
$roamingBase = Join-Path $env:APPDATA "Autodesk\$acadDirName\$($target.Version)\chs\Support"
|
||
$installSupport = Join-Path $target.Location "Support"
|
||
|
||
$candidateDirs = @($roamingBase, $installSupport) | Select-Object -Unique
|
||
$supDir = $null
|
||
foreach ($d in $candidateDirs) {
|
||
if (Test-Path $d) { $supDir = $d; break }
|
||
}
|
||
|
||
if (-not $supDir) {
|
||
Write-Host " 未找到 Support 目录,跳过" -ForegroundColor DarkGray
|
||
} else {
|
||
$lspPath = Join-Path $supDir 'acaddoc.lsp'
|
||
if (-not (Test-Path $lspPath)) {
|
||
Write-Host " acaddoc.lsp 不存在,跳过" -ForegroundColor DarkGray
|
||
} else {
|
||
# 读取(尝试 GB2312,失败则用默认编码)
|
||
$content = $null
|
||
try {
|
||
$content = [System.IO.File]::ReadAllText($lspPath, [System.Text.Encoding]::GetEncoding('GB2312'))
|
||
} catch {
|
||
$content = Get-Content $lspPath -Raw -ErrorAction SilentlyContinue
|
||
}
|
||
|
||
if (-not $content) {
|
||
Write-Host " acaddoc.lsp 为空或无法读取,跳过" -ForegroundColor DarkGray
|
||
} elseif ($content -notmatch 'CADCJ|cadcj') {
|
||
Write-Host " acaddoc.lsp 中无 CADCJ 加载逻辑,跳过" -ForegroundColor DarkGray
|
||
} else {
|
||
# 判断是否为纯 CADCJ 文件(以 ;;; CADCJ 开头或整个文件就是 CADCJ 块)
|
||
# 移除 CADCJ 加载块(从 ;;; CADCJ 标记开始到 (princ) 结束)
|
||
$pattern = '(?s)\s*;;; CADCJ.*?\(princ\)\s*'
|
||
$newContent = [regex]::Replace($content, $pattern, "`r`n")
|
||
# 清理多余空行
|
||
$newContent = $newContent -replace "(`r`n){3,}", "`r`n`r`n"
|
||
$newContent = $newContent.TrimEnd()
|
||
|
||
try {
|
||
if ([string]::IsNullOrWhiteSpace($newContent)) {
|
||
# 文件清空了,删除文件
|
||
Remove-Item $lspPath -Force
|
||
Write-Host " 已删除: $lspPath(文件仅含 CADCJ 内容)" -ForegroundColor Green
|
||
} else {
|
||
# 保留其他内容,只移除 CADCJ 块
|
||
[System.IO.File]::WriteAllText($lspPath, $newContent + "`r`n", [System.Text.Encoding]::GetEncoding('GB2312'))
|
||
Write-Host " 已清理 CADCJ 加载逻辑,保留其他内容: $lspPath" -ForegroundColor Green
|
||
}
|
||
} catch {
|
||
# 写入失败时提权
|
||
Write-Host " 写入失败,尝试提权: $($_.Exception.Message)" -ForegroundColor Yellow
|
||
$tmpLsp = Join-Path $env:TEMP 'cadcj_acaddoc_clean.lsp'
|
||
if ([string]::IsNullOrWhiteSpace($newContent)) {
|
||
$delCmd = "Remove-Item '$lspPath' -Force -ErrorAction SilentlyContinue"
|
||
$p = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile","-Command",$delCmd -Verb RunAs -Wait -PassThru
|
||
if ($p.ExitCode -eq 0) {
|
||
Write-Host " 已删除(提权): $lspPath" -ForegroundColor Green
|
||
}
|
||
} else {
|
||
[System.IO.File]::WriteAllText($tmpLsp, $newContent + "`r`n", [System.Text.Encoding]::GetEncoding('GB2312'))
|
||
$copyCmd = "Copy-Item '$tmpLsp' '$lspPath' -Force"
|
||
$p = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile","-Command",$copyCmd -Verb RunAs -Wait -PassThru
|
||
if ($p.ExitCode -eq 0) {
|
||
Write-Host " 已清理(提权): $lspPath" -ForegroundColor Green
|
||
}
|
||
}
|
||
Remove-Item $tmpLsp -Force -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# --- 完成 ---
|
||
Write-Host "======================================================" -ForegroundColor Cyan
|
||
Write-Host " 卸载完成!" -ForegroundColor Green
|
||
Write-Host "======================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "卸载摘要:" -ForegroundColor White
|
||
Write-Host " AutoCAD: $($target.Product) ($($target.Version))" -ForegroundColor White
|
||
Write-Host " HKLM 注册: 已删除 CADCJ 节点" -ForegroundColor White
|
||
Write-Host " TRUSTEDPATHS: 已移除 $scriptDir" -ForegroundColor White
|
||
Write-Host " acaddoc.lsp: 已清理 CADCJ 加载逻辑" -ForegroundColor White
|
||
Write-Host ""
|
||
Write-Host "插件文件本身未删除(cadcj.dll 等),如需彻底删除请手动移除目录:" -ForegroundColor Yellow
|
||
Write-Host " $scriptDir" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
if (-not $env:CADCJ_SILENT) { Read-Host "按回车退出" }
|