Files
ctbjrj/cadbt/cadbt/cadcj/卸载CAD插件.ps1
T

264 lines
12 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ===========================================================================
# 成套报价 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 "按回车退出" }