diff --git a/internal/app/methods_update.go b/internal/app/methods_update.go index ce812e9a..6b5e9bb3 100644 --- a/internal/app/methods_update.go +++ b/internal/app/methods_update.go @@ -252,7 +252,7 @@ func (a *App) InstallUpdateAndRestart() connection.QueryResult { return connection.QueryResult{Success: false, Message: a.appText("app.update.backend.message.no_downloaded_package", nil)} } - if stdRuntime.GOOS == "windows" && !shouldWindowsUpdateLaunchDownloadedAssetDirectly(staged.FilePath) { + if stdRuntime.GOOS == "windows" { if err := ensureWindowsUpdateTargetWritable(updateResolveInstallTarget()); err != nil { return connection.QueryResult{ Success: false, @@ -1366,7 +1366,6 @@ for %%I in ("%TARGET%") do set "TARGET_NAME=%%~nxI" for %%I in ("%TARGET%") do set "TARGET_DIR=%%~dpI" for %%I in ("%SOURCE%") do set "SOURCE_EXT=%%~xI" set "SOURCE_EXE=" -set "SOURCE_DIR=" if /I "%SOURCE_EXT%"==".zip" ( set "EXTRACT_DIR=%STAGED%\_extract" @@ -1414,28 +1413,11 @@ rem -- Win10 needs extra time for kernel to release exe file handles -- timeout /t 3 /nobreak >nul call :log cooldown finished, starting file replace -if /I "%SOURCE_EXT%"==".zip" goto replace_from_zip -goto launch_downloaded_exe - -:launch_downloaded_exe -if not exist "%SOURCE_EXE%" ( - call :log downloaded executable not found: %SOURCE_EXE% - exit /b 1 +:replace_binary +if /I "%SOURCE_EXE%"=="%TARGET%" ( + call :log downloaded executable already at target path, skip replace + goto move_done ) -call :log launching downloaded executable: %SOURCE_EXE% -start "" /D "%SOURCE_DIR%" "%SOURCE_EXE%" >> "%LOG_FILE%" 2>&1 -if %ERRORLEVEL% NEQ 0 ( - call :log cmd start failed, trying powershell Start-Process - powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -FilePath '%SOURCE_EXE%' -WorkingDirectory '%SOURCE_DIR%'" >> "%LOG_FILE%" 2>&1 - if !ERRORLEVEL! NEQ 0 ( - call :log relaunch failed - exit /b 1 - ) -) -call :log update finished -exit /b 0 - -:replace_from_zip set /a RETRY=0 :move_retry call :log attempt !RETRY!: trying rename-then-copy strategy @@ -1473,6 +1455,7 @@ exit /b 1 :move_done del /F /Q "%TARGET_OLD%" >> "%LOG_FILE%" 2>&1 +if exist "%SOURCE%" del /F /Q "%SOURCE%" >> "%LOG_FILE%" 2>&1 start "" /D "%TARGET_DIR%" "%TARGET%" >> "%LOG_FILE%" 2>&1 if %ERRORLEVEL% NEQ 0 ( call :log cmd start failed, trying powershell Start-Process diff --git a/internal/app/methods_update_test.go b/internal/app/methods_update_test.go index f95a9ba1..20725a07 100644 --- a/internal/app/methods_update_test.go +++ b/internal/app/methods_update_test.go @@ -563,7 +563,7 @@ func TestShouldWindowsUpdateLaunchDownloadedAssetDirectly(t *testing.T) { } } -func TestBuildWindowsScriptLaunchesDownloadedExeDirectly(t *testing.T) { +func TestBuildWindowsScriptReplacesTargetWithDownloadedExe(t *testing.T) { script := buildWindowsScript( `C:\GoNavi\GoNavi-dev-93dc696-Windows-Amd64.exe`, `C:\GoNavi\GoNavi-dev-00d70d2-Windows-Amd64.exe`, @@ -573,15 +573,20 @@ func TestBuildWindowsScriptLaunchesDownloadedExeDirectly(t *testing.T) { ) mustContain := []string{ - `goto launch_downloaded_exe`, - `call :log launching downloaded executable: %SOURCE_EXE%`, - `start "" /D "%SOURCE_DIR%" "%SOURCE_EXE%"`, + `:replace_binary`, + `move /Y "%TARGET%" "%TARGET_OLD%"`, + `copy /Y "%SOURCE_EXE%" "%TARGET%"`, + `if exist "%SOURCE%" del /F /Q "%SOURCE%"`, + `start "" /D "%TARGET_DIR%" "%TARGET%"`, } for _, want := range mustContain { if !strings.Contains(script, want) { t.Fatalf("windows update script missing required token: %s\nscript:\n%s", want, script) } } + if strings.Contains(script, "launch_downloaded_exe") { + t.Fatalf("windows update script should not launch downloaded exe side-by-side\nscript:\n%s", script) + } } func TestExpectedAssetNameForExecutableUsesLinuxWebKit41Suffix(t *testing.T) {