@@ -84,10 +84,19 @@ pub fn check_for_updates() -> Result<UpdateCheckResult, String> {
8484}
8585
8686pub fn begin_winget_update ( ) -> Result < ( ) , String > {
87- let command = winget_upgrade_command ( ) ;
87+ let current_exe =
88+ std:: env:: current_exe ( ) . map_err ( |e| format ! ( "Unable to locate current executable: {e}" ) ) ?;
89+ let current_dir = current_exe
90+ . parent ( )
91+ . ok_or_else ( || "Unable to determine the app directory for restart." . to_string ( ) ) ?;
92+ let command = winget_upgrade_command (
93+ std:: process:: id ( ) ,
94+ & current_exe. to_string_lossy ( ) ,
95+ & current_dir. to_string_lossy ( ) ,
96+ ) ;
97+
8898 Command :: new ( "powershell.exe" )
8999 . arg ( "-NoLogo" )
90- . arg ( "-NoExit" )
91100 . arg ( "-Command" )
92101 . arg ( & command)
93102 . creation_flags ( CREATE_NEW_CONSOLE )
@@ -335,8 +344,39 @@ fn updates_dir() -> Result<PathBuf, String> {
335344 . ok_or_else ( || "Unable to resolve a writable local updates directory." . to_string ( ) )
336345}
337346
338- fn winget_upgrade_command ( ) -> String {
339- format ! ( "winget upgrade --id {WINGET_PACKAGE_ID} --exact" )
347+ fn winget_upgrade_command ( pid : u32 , target : & str , working_dir : & str ) -> String {
348+ let target = powershell_single_quoted ( target) ;
349+ let working_dir = powershell_single_quoted ( working_dir) ;
350+ let package_id = WINGET_PACKAGE_ID ;
351+
352+ format ! (
353+ concat!(
354+ "$ErrorActionPreference = 'Stop'; " ,
355+ "$pidToWait = {pid}; " ,
356+ "$target = '{target}'; " ,
357+ "$workingDir = '{working_dir}'; " ,
358+ "try {{ Wait-Process -Id $pidToWait -Timeout 30 -ErrorAction Stop }} catch {{ }}; " ,
359+ "winget upgrade --id {package_id} --exact; " ,
360+ "$exitCode = $LASTEXITCODE; " ,
361+ "if ($exitCode -eq 0) {{ " ,
362+ "Start-Sleep -Seconds 2; " ,
363+ "Start-Process -FilePath $target -WorkingDirectory $workingDir; " ,
364+ "exit 0 " ,
365+ "}}; " ,
366+ "Write-Host ''; " ,
367+ "Write-Host 'WinGet update failed with exit code' $exitCode; " ,
368+ "Read-Host 'Press Enter to close'; " ,
369+ "exit $exitCode"
370+ ) ,
371+ pid = pid,
372+ target = target,
373+ working_dir = working_dir,
374+ package_id = package_id,
375+ )
376+ }
377+
378+ fn powershell_single_quoted ( value : & str ) -> String {
379+ value. replace ( '\'' , "''" )
340380}
341381
342382fn backup_path_for ( target : & Path ) -> PathBuf {
@@ -424,10 +464,17 @@ fn winget_install_roots() -> Vec<PathBuf> {
424464}
425465
426466fn normalize_path ( path : & Path ) -> String {
427- path. to_string_lossy ( )
467+ let normalized = path
468+ . to_string_lossy ( )
428469 . replace ( '/' , "\\ " )
429470 . trim_end_matches ( '\\' )
430- . to_ascii_lowercase ( )
471+ . to_ascii_lowercase ( ) ;
472+
473+ normalized
474+ . strip_prefix ( "\\ \\ ?\\ unc\\ " )
475+ . map ( |rest| format ! ( "\\ \\ {rest}" ) )
476+ . or_else ( || normalized. strip_prefix ( "\\ \\ ?\\ " ) . map ( str:: to_owned) )
477+ . unwrap_or ( normalized)
431478}
432479
433480fn is_version_newer ( candidate : & str , current : & str ) -> bool {
0 commit comments