fix(desktop): avoid full install scan on user upgrades

This commit is contained in:
程序员阿江(Relakkes) 2026-07-14 04:42:14 +08:00
parent 406f603015
commit 835213da53
3 changed files with 31 additions and 6 deletions

View File

@ -198,7 +198,7 @@ FunctionEnd
StrCpy $1 "Recovery helper failed without diagnostic output (exit code $0)"
${EndIf}
StrCpy $R2 "$1" 360
MessageBox MB_ICONSTOP|MB_OK "Claude Code Haha stopped setup before removing the old version. Reason: $R2$\r$\n$\r$\nClose the app and retry. If the reason mentions an elevated installer, launch setup normally instead of using Run as administrator.$\r$\n$\r$\nClaude Code Haha 已在删除旧版本前停止安装。原因:$R2$\r$\n$\r$\n请关闭旧程序后重试如果原因提到安装器权限过高请直接双击运行不要使用“以管理员身份运行”。旧版本和原数据尚未删除。"
MessageBox MB_ICONSTOP|MB_OK "Claude Code Haha stopped setup before removing the old version. Reason: $R2$\r$\n$\r$\nClose the app and retry. If the reason mentions an elevated installer, launch setup normally instead of using Run as administrator.$\r$\n$\r$\nClaude Code Haha 已在删除旧版本前停止安装。原因:$R2$\r$\n$\r$\n请关闭旧程序后重试如果原因提到安装器权限过高请直接双击运行不要使用“以管理员身份运行”。旧版本和原数据尚未删除。" /SD IDOK
SetErrorLevel 20
Quit
${EndIf}

View File

@ -636,6 +636,7 @@ function Write-AppModeAtomically {
function Invoke-LegacyRecovery {
param(
[Parameter(Mandatory = $true)][string[]]$InstallDirs,
[string[]]$SharedInstallDirs = @(),
[Parameter(Mandatory = $true)][string]$UserDataDir,
[Parameter(Mandatory = $true)][string]$RecoveryRoot,
[Parameter(Mandatory = $true)][string]$ProcessName,
@ -656,7 +657,11 @@ function Invoke-LegacyRecovery {
-UserDataDir $UserDataDir `
-ActiveConfigDir $ActiveConfigDir `
-ActiveConfigManaged $ActiveConfigManaged
Assert-NoUndiscoveredLegacySources -InstallDirs $existingInstallDirs -ActiveSource $source
$potentialSharedInstallDirs = @(Get-PotentialInstallDirs -InstallDirs $SharedInstallDirs)
$existingSharedInstallDirs = @(Get-ExistingInstallDirs -InstallDirs $potentialSharedInstallDirs)
if ($existingSharedInstallDirs.Count -gt 0) {
Assert-NoUndiscoveredLegacySources -InstallDirs $existingSharedInstallDirs -ActiveSource $source
}
if ([string]::IsNullOrWhiteSpace([string]$source)) {
return $null
}
@ -793,6 +798,19 @@ function Run-SelfTest {
-ActiveConfigDir '' -InstallerIdentitySafety 'untrusted-elevated' -SkipProcessCheck
Assert-SelfTest -Condition ($null -eq $elevatedDefaultResult) -Message 'elevated default-mode reinstall was blocked without legacy data'
$perUserInstall = Join-Path $testRoot 'per-user install'
$perUserExternalTarget = Join-Path $testRoot 'per-user external target'
$perUserAppPayload = Join-Path $perUserInstall 'resources\app payload'
New-Item -ItemType Directory -Path (Join-Path $perUserInstall 'resources') -Force | Out-Null
New-Item -ItemType Directory -Path $perUserExternalTarget -Force | Out-Null
New-Item -ItemType Junction -Path $perUserAppPayload -Target $perUserExternalTarget | Out-Null
$perUserResult = Invoke-LegacyRecovery `
-InstallDirs @($perUserInstall) `
-UserDataDir (Join-Path $testRoot 'per-user app data') `
-RecoveryRoot (Join-Path $testRoot 'per-user recovery') -ProcessName $ProcessName `
-ActiveConfigDir '' -SkipProcessCheck
Assert-SelfTest -Condition ($null -eq $perUserResult) -Message 'per-user default-mode reinstall scanned the packaged application tree'
$wrongIdentityInstall = Join-Path $testRoot 'registered shared install'
$wrongIdentityData = Join-Path $wrongIdentityInstall 'custom data'
New-Item -ItemType Directory -Path $wrongIdentityData -Force | Out-Null
@ -801,7 +819,7 @@ function Run-SelfTest {
$wrongIdentityFailed = $false
try {
Invoke-LegacyRecovery `
-InstallDirs @($wrongIdentityInstall) `
-InstallDirs @($wrongIdentityInstall) -SharedInstallDirs @($wrongIdentityInstall) `
-UserDataDir (Join-Path $testRoot 'wrong identity app data') `
-RecoveryRoot (Join-Path $testRoot 'wrong identity recovery') -ProcessName $ProcessName `
-ActiveConfigDir '' -InstallerIdentitySafety 'untrusted-elevated' -SkipProcessCheck | Out-Null
@ -833,7 +851,8 @@ function Run-SelfTest {
$sharedFailed = $false
try {
Invoke-LegacyRecovery `
-InstallDirs @($sharedInstall) -UserDataDir (Join-Path $testRoot 'shared app data') `
-InstallDirs @($sharedInstall) -SharedInstallDirs @($sharedInstall) `
-UserDataDir (Join-Path $testRoot 'shared app data') `
-RecoveryRoot (Join-Path $testRoot 'shared recovery') -ProcessName $ProcessName `
-ActiveConfigDir $activeExternal -ActiveConfigManaged '' -SkipProcessCheck | Out-Null
} catch {
@ -851,7 +870,8 @@ function Run-SelfTest {
$otherUserFailed = $false
try {
Invoke-LegacyRecovery `
-InstallDirs @($otherUserInstall) -UserDataDir $currentUserMode `
-InstallDirs @($otherUserInstall) -SharedInstallDirs @($otherUserInstall) `
-UserDataDir $currentUserMode `
-RecoveryRoot (Join-Path $testRoot 'other user recovery') -ProcessName $ProcessName `
-ActiveConfigDir '' -SkipProcessCheck | Out-Null
} catch {
@ -938,7 +958,8 @@ function Run-SelfTest {
$junctionFailed = $false
try {
Invoke-LegacyRecovery `
-InstallDirs @($junctionInstall) -UserDataDir (Join-Path $testRoot 'junction app data') `
-InstallDirs @($junctionInstall) -SharedInstallDirs @($junctionInstall) `
-UserDataDir (Join-Path $testRoot 'junction app data') `
-RecoveryRoot (Join-Path $testRoot 'junction recovery') -ProcessName $ProcessName `
-ActiveConfigDir '' -SkipProcessCheck | Out-Null
} catch {
@ -960,6 +981,7 @@ try {
$result = Invoke-LegacyRecovery `
-InstallDirs @($PerUserInstallDir, $PerMachineInstallDir, $CandidateInstallDir) `
-SharedInstallDirs @($PerMachineInstallDir) `
-UserDataDir $UserDataDir `
-RecoveryRoot $RecoveryRoot `
-ProcessName $ProcessName `

View File

@ -514,6 +514,7 @@ describe('release desktop workflow', () => {
expect(installerHook).toContain('Var ccHahaPerMachineInstallLocation')
expect(installerHook).toMatch(/!macro CcHahaRunLegacyRecovery[\s\S]*ReadRegStr \$ccHahaPerUserInstallLocation[\s\S]*\$ccHahaPerUserUninstallString == ""[\s\S]*No registered installation needs legacy data recovery[\s\S]*Call CcHahaRecoverLegacy/)
expect(installerHook).toContain('SetErrorLevel 20')
expect(installerHook).toContain('/SD IDOK')
expect(installerHook).toContain('Quit')
expect(recoveryHelper).toContain('function Get-LegacyActiveSource')
expect(recoveryHelper).toContain('function Get-PotentialInstallDirs')
@ -529,6 +530,8 @@ describe('release desktop workflow', () => {
expect(recoveryHelper).toContain('Multiple distinct legacy data sources')
expect(recoveryHelper).toContain('Active CLAUDE_CONFIG_DIR is managed outside Claude Code Haha')
expect(recoveryHelper).toContain('Test-LexicalPathAtOrBelow')
expect(recoveryHelper).toContain('-SharedInstallDirs @($PerMachineInstallDir)')
expect(recoveryHelper).toContain('per-user default-mode reinstall scanned the packaged application tree')
expect(recoveryHelper).toContain('untrusted-elevated')
expect(recoveryHelper).toContain('External CLAUDE_CONFIG_DIR is active while install-contained legacy data still exists')
expect(recoveryHelper).toMatch(/\$source = Get-UnsafeLegacySource[\s\S]*Assert-NoRunningApplication/)