From d7c4edda20e426272cb8dd282efe3bbab2c2ea1d Mon Sep 17 00:00:00 2001 From: Fedor Indutnyy Date: Wed, 12 Jan 2022 11:40:03 -0800 Subject: [PATCH] fix(NSIS): prevent partial overwrites `Nsis7z::Extract` ignores the errors when copying the files and thus can leave us with the app that has old asar and bindings, but new assets. In addition to that, the app will firmly believe that it is still running an old version and would attempt to repeatedly auto-update until fixed, leading to excessive bandwidth use and very unhappy customers. This change extracts the contents of 7z archive into a separate directory before attempting to copy them with `CopyFiles` function that (unlike `Nsis7z::Extract`) does detect and report failures. To make our lives easier the `CopyFiles` will also erase all files on a failure so after retrying a few times we will ultimately have to fallback to old 7z extraction directly into output folder. --- .changeset/nervous-cherries-speak.md | 5 +++ .../nsis/include/extractAppPackage.nsh | 42 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .changeset/nervous-cherries-speak.md diff --git a/.changeset/nervous-cherries-speak.md b/.changeset/nervous-cherries-speak.md new file mode 100644 index 00000000000..9ae0c8006a7 --- /dev/null +++ b/.changeset/nervous-cherries-speak.md @@ -0,0 +1,5 @@ +--- +"app-builder-lib": patch +--- + +fix(nsis): Prevent partial updates from happening diff --git a/packages/app-builder-lib/templates/nsis/include/extractAppPackage.nsh b/packages/app-builder-lib/templates/nsis/include/extractAppPackage.nsh index 367aaaec7eb..dff19261c0d 100644 --- a/packages/app-builder-lib/templates/nsis/include/extractAppPackage.nsh +++ b/packages/app-builder-lib/templates/nsis/include/extractAppPackage.nsh @@ -90,5 +90,45 @@ !macroend !macro extractUsing7za FILE - Nsis7z::Extract "${FILE}" + Push $OUTDIR + CreateDirectory "$PLUGINSDIR\7z-out" + ClearErrors + SetOutPath "$PLUGINSDIR\7z-out" + Nsis7z::Extract "${FILE}" + Pop $R0 + SetOutPath $R0 + + # Retry counter + StrCpy $R1 0 + + LoopExtract7za: + IntOp $R1 $R1 + 1 + + CopyFiles /SILENT "$PLUGINSDIR\7z-out\*" $OUTDIR + IfErrors 0 DoneExtract7za + + ${if} $R1 > 1 + DetailPrint `Can't modify "${PRODUCT_NAME}"'s files.` + ${if} $R1 < 5 + # Try copying a few times before giving up + Goto LoopExtract7za + ${else} + MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY RetryExtract7za + ${endIf} + + # CopyFiles will remove all overwritten files when it encounters an + # issue and make app non-launchable. Extract over from the archive + # ignoring the failures so at least we will partially update and the + # app would start. + Nsis7z::Extract "${FILE}" + Quit + ${else} + Goto LoopExtract7za + ${endIf} + + RetryExtract7za: + Sleep 1000 + Goto LoopExtract7za + + DoneExtract7za: !macroend