Index: mptrack/UpdateCheck.cpp =================================================================== --- mptrack/UpdateCheck.cpp (revision 23480) +++ mptrack/UpdateCheck.cpp (working copy) @@ -937,7 +937,7 @@ -static const char updateScript[] = R"vbs( +static const char updateScript_vbs[] = R"vbs( Wscript.Echo Wscript.Echo "OpenMPT portable Update" @@ -1016,7 +1016,59 @@ )vbs"; +static const char updateScript_ps1[] = R"ps1( +param( + [String]$zip="", + [String]$subfolder="", + [String]$dst="", + [String]$restartbinary="") + +Write-Output "" +Write-Output "OpenMPT portable Update" +Write-Output "=======================" + +Write-Output "[ 0%] Waiting for OpenMPT to close..." +Start-Sleep -Seconds 2 + +Write-Output "[ 10%] Changing to temporary directory..." +Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) + +Write-Output "[ 20%] Decompressing update..." +Expand-Archive -Path $zip -DestinationPath (Join-Path -Path (Resolve-Path -Path ".") -ChildPath "tmp") -Force + +Write-Output "[ 40%] Installing update..." +if (($subfolder -eq "") -or ($subfolder -eq ".")) { + Copy-Item -Path (Join-Path -Path (Join-Path -Path (Resolve-Path -Path ".") -ChildPath "tmp") -ChildPath "*") -Destination $dst -Recurse -Force +} else { + Copy-Item -Path (Join-Path -Path (Join-Path -Path (Join-Path -Path (Resolve-Path -Path ".") -ChildPath "tmp") -ChildPath $subfolder) -ChildPath "*") -Destination $dst -Recurse -Force +} + +Write-Output "[ 60%] Deleting temporary directory..." +Remove-Item -Path (Join-Path -Path (Resolve-Path -Path ".") -ChildPath "tmp") -Recurse -Force + +Write-Output "[ 80%] Restarting OpenMPT..." +Start-Process -FilePath (Join-Path -Path (Resolve-Path -Path $dst) -ChildPath $restartbinary) -WorkingDirectory $dst + +Write-Output "[100%] Update successful!" +Write-Output "" +Start-Sleep -Seconds 1 + +Write-Output "Closing update window in 5 seconds..." +Start-Sleep -Seconds 1 +Write-Output "Closing update window in 4 seconds..." +Start-Sleep -Seconds 1 +Write-Output "Closing update window in 3 seconds..." +Start-Sleep -Seconds 1 +Write-Output "Closing update window in 2 seconds..." +Start-Sleep -Seconds 1 +Write-Output "Closing update window in 1 seconds..." +Start-Sleep -Seconds 1 +Write-Output "Closing update window..." + +)ps1"; + + class CDoUpdate: public CProgressDialog { private: @@ -1306,35 +1358,75 @@ } } else if(download.type == U_("archive") && downloadinfo.autoupdate_archive) { - try + if(mpt::osinfo::windows::Version::Current().IsAtLeast(mpt::osinfo::windows::Version::Win10, 22000)) { - mpt::IO::SafeOutputFile file(dirTempOpenMPTUpdates + P_("update.vbs"), std::ios::binary); - file.stream().imbue(std::locale::classic()); - file.stream().exceptions(std::ios::failbit | std::ios::badbit); - mpt::IO::WriteRaw(file.stream(), mpt::as_span(std::string(updateScript))); - } catch(...) + try + { + mpt::IO::SafeOutputFile file(dirTempOpenMPTUpdates + P_("update.ps1"), std::ios::binary); + file.stream().imbue(std::locale::classic()); + file.stream().exceptions(std::ios::failbit | std::ios::badbit); + mpt::IO::WriteRaw(file.stream(), mpt::as_span(std::string(updateScript_ps1))); + } catch(...) + { + throw Error(U_("Error creating update script.")); + } + std::vector arguments; + arguments.push_back(U_("-ExecutionPolicy")); + arguments.push_back(U_("Unrestricted")); + arguments.push_back(U_("\"") + (dirTempOpenMPTUpdates + P_("update.ps1")).ToUnicode() + U_("\"")); + arguments.push_back(U_("-zip")); + arguments.push_back(U_("\"") + updateFilename.ToUnicode() + U_("\"")); + arguments.push_back(U_("-subfolder")); + arguments.push_back(U_("\"") + (downloadinfo.autoupdate_archive->subfolder.empty() ? U_(".") : downloadinfo.autoupdate_archive->subfolder) + U_("\"")); + arguments.push_back(U_("-dst")); + arguments.push_back(U_("\"") + theApp.GetInstallPath().WithoutTrailingSlash().ToUnicode() + U_("\"")); + arguments.push_back(U_("-restartbinary")); + arguments.push_back(U_("\"") + downloadinfo.autoupdate_archive->restartbinary + U_("\"")); + if(theApp.IsSourceTreeMode()) + { + throw Warning(MPT_UFORMAT("Refusing to launch update '{} {}' when running from source tree.")(P_("cscript.exe"), mpt::join_format(arguments, U_(" ")))); + } + if(reinterpret_cast(ShellExecute(NULL, NULL, + P_("powershell").AsNative().c_str(), + mpt::ToWin(mpt::join_format(arguments, U_(" "))).c_str(), + dirTempOpenMPTUpdates.AsNative().c_str(), + SW_SHOWDEFAULT)) < 32) + { + throw Error(U_("Error launching update.")); + } + wantClose = true; + } else { - throw Error(U_("Error creating update script.")); + try + { + mpt::IO::SafeOutputFile file(dirTempOpenMPTUpdates + P_("update.vbs"), std::ios::binary); + file.stream().imbue(std::locale::classic()); + file.stream().exceptions(std::ios::failbit | std::ios::badbit); + mpt::IO::WriteRaw(file.stream(), mpt::as_span(std::string(updateScript_vbs))); + } catch(...) + { + throw Error(U_("Error creating update script.")); + } + std::vector arguments; + arguments.push_back(U_("\"") + (dirTempOpenMPTUpdates + P_("update.vbs")).ToUnicode() + U_("\"")); + arguments.push_back(U_("\"") + updateFilename.ToUnicode() + U_("\"")); + arguments.push_back(U_("\"") + (downloadinfo.autoupdate_archive->subfolder.empty() ? U_(".") : downloadinfo.autoupdate_archive->subfolder) + U_("\"")); + arguments.push_back(U_("\"") + theApp.GetInstallPath().WithoutTrailingSlash().ToUnicode() + U_("\"")); + arguments.push_back(U_("\"") + downloadinfo.autoupdate_archive->restartbinary + U_("\"")); + if(theApp.IsSourceTreeMode()) + { + throw Warning(MPT_UFORMAT("Refusing to launch update '{} {}' when running from source tree.")(P_("cscript.exe"), mpt::join_format(arguments, U_(" ")))); + } + if(reinterpret_cast(ShellExecute(NULL, NULL, + P_("cscript.exe").AsNative().c_str(), + mpt::ToWin(mpt::join_format(arguments, U_(" "))).c_str(), + dirTempOpenMPTUpdates.AsNative().c_str(), + SW_SHOWDEFAULT)) < 32) + { + throw Error(U_("Error launching update.")); + } + wantClose = true; } - std::vector arguments; - arguments.push_back(U_("\"") + (dirTempOpenMPTUpdates + P_("update.vbs")).ToUnicode() + U_("\"")); - arguments.push_back(U_("\"") + updateFilename.ToUnicode() + U_("\"")); - arguments.push_back(U_("\"") + (downloadinfo.autoupdate_archive->subfolder.empty() ? U_(".") : downloadinfo.autoupdate_archive->subfolder) + U_("\"")); - arguments.push_back(U_("\"") + theApp.GetInstallPath().WithoutTrailingSlash().ToUnicode() + U_("\"")); - arguments.push_back(U_("\"") + downloadinfo.autoupdate_archive->restartbinary + U_("\"")); - if(theApp.IsSourceTreeMode()) - { - throw Warning(MPT_UFORMAT("Refusing to launch update '{} {}' when running from source tree.")(P_("cscript.exe"), mpt::join_format(arguments, U_(" ")))); - } - if(reinterpret_cast(ShellExecute(NULL, NULL, - P_("cscript.exe").AsNative().c_str(), - mpt::ToWin(mpt::join_format(arguments, U_(" "))).c_str(), - dirTempOpenMPTUpdates.AsNative().c_str(), - SW_SHOWDEFAULT)) < 32) - { - throw Error(U_("Error launching update.")); - } - wantClose = true; } else { CTrackApp::OpenDirectory(dirTempOpenMPTUpdates);