diff --git a/.github/workflows/template-tauri-build-windows-x64.yml b/.github/workflows/template-tauri-build-windows-x64.yml index a074d2e56..4d5c2befb 100644 --- a/.github/workflows/template-tauri-build-windows-x64.yml +++ b/.github/workflows/template-tauri-build-windows-x64.yml @@ -95,8 +95,6 @@ jobs: # Update tauri.conf.json jq --arg version "${{ inputs.new_version }}" '.version = $version | .bundle.createUpdaterArtifacts = true' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json - # jq '.bundle.windows.nsis.template = "tauri.bundle.windows.nsis.template"' ./src-tauri/tauri.windows.conf.json > /tmp/tauri.windows.conf.json - # mv /tmp/tauri.windows.conf.json ./src-tauri/tauri.windows.conf.json jq --arg version "${{ inputs.new_version }}" '.version = $version' web-app/package.json > /tmp/package.json mv /tmp/package.json web-app/package.json @@ -104,47 +102,19 @@ jobs: echo "---------Cargo.toml---------" cat ./src-tauri/Cargo.toml - generate_build_version() { - ### Examble - ### input 0.5.6 output will be 0.5.6 and 0.5.6.0 - ### input 0.5.6-rc2-beta output will be 0.5.6 and 0.5.6.2 - ### input 0.5.6-1213 output will be 0.5.6 and and 0.5.6.1213 - local new_version="$1" - local base_version - local t_value - - # Check if it has a "-" - if [[ "$new_version" == *-* ]]; then - base_version="${new_version%%-*}" # part before - - suffix="${new_version#*-}" # part after - - - # Check if it is rcX-beta - if [[ "$suffix" =~ ^rc([0-9]+)-beta$ ]]; then - t_value="${BASH_REMATCH[1]}" - else - t_value="$suffix" - fi - else - base_version="$new_version" - t_value="0" - fi - - # Export two values - new_base_version="$base_version" - new_build_version="${base_version}.${t_value}" - } - generate_build_version ${{ inputs.new_version }} - sed -i "s/jan_version/$new_base_version/g" ./src-tauri/tauri.bundle.windows.nsis.template - sed -i "s/jan_build/$new_build_version/g" ./src-tauri/tauri.bundle.windows.nsis.template - # Temporarily enable devtool on prod build ctoml ./src-tauri/Cargo.toml dependencies.tauri.features[] "devtools" cat ./src-tauri/Cargo.toml # Change app name for beta and nightly builds if [ "${{ inputs.channel }}" != "stable" ]; then + # Update updater endpoint jq '.plugins.updater.endpoints = ["https://delta.jan.ai/${{ inputs.channel }}/latest.json"]' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json + + # Update product name + jq --arg name "Jan-${{ inputs.channel }}" '.productName = $name' ./src-tauri/tauri.conf.json > /tmp/tauri.conf.json + mv /tmp/tauri.conf.json ./src-tauri/tauri.conf.json chmod +x .github/scripts/rename-tauri-app.sh .github/scripts/rename-tauri-app.sh ./src-tauri/tauri.conf.json ${{ inputs.channel }} @@ -161,15 +131,8 @@ jobs: chmod +x .github/scripts/rename-workspace.sh .github/scripts/rename-workspace.sh ./package.json ${{ inputs.channel }} cat ./package.json - - sed -i "s/jan_productname/Jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template - sed -i "s/jan_mainbinaryname/jan-${{ inputs.channel }}/g" ./src-tauri/tauri.bundle.windows.nsis.template else - sed -i "s/jan_productname/Jan/g" ./src-tauri/tauri.bundle.windows.nsis.template - sed -i "s/jan_mainbinaryname/jan/g" ./src-tauri/tauri.bundle.windows.nsis.template fi - echo "---------nsis.template---------" - cat ./src-tauri/tauri.bundle.windows.nsis.template - name: Install AzureSignTool run: | diff --git a/src-tauri/tauri.bundle.windows.nsis.template b/src-tauri/tauri.bundle.windows.nsis.template deleted file mode 100644 index 2cd878dc2..000000000 --- a/src-tauri/tauri.bundle.windows.nsis.template +++ /dev/null @@ -1,1007 +0,0 @@ -Unicode true -ManifestDPIAware true -; Add in `dpiAwareness` `PerMonitorV2` to manifest for Windows 10 1607+ (note this should not affect lower versions since they should be able to ignore this and pick up `dpiAware` `true` set by `ManifestDPIAware true`) -; Currently undocumented on NSIS's website but is in the Docs folder of source tree, see -; https://github.com/kichik/nsis/blob/5fc0b87b819a9eec006df4967d08e522ddd651c9/Docs/src/attributes.but#L286-L300 -; https://github.com/tauri-apps/tauri/pull/10106 -ManifestDPIAwareness PerMonitorV2 - -!if "lzma" == "none" - SetCompress off -!else - ; Set the compression algorithm. We default to LZMA. - SetCompressor /SOLID "lzma" -!endif - -!include MUI2.nsh -!include FileFunc.nsh -!include x64.nsh -!include WordFunc.nsh -!include "utils.nsh" -!include "FileAssociation.nsh" -!include "Win\COM.nsh" -!include "Win\Propkey.nsh" -!include "StrFunc.nsh" -${StrCase} -${StrLoc} - - -!define WEBVIEW2APPGUID "{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" - -!define MANUFACTURER "ai" -!define PRODUCTNAME "jan_productname" -!define VERSION "jan_version" -!define VERSIONWITHBUILD "jan_build" -!define HOMEPAGE "" -!define INSTALLMODE "currentUser" -!define LICENSE "" -!define INSTALLERICON "D:\a\jan\jan\src-tauri\icons\icon.ico" -!define SIDEBARIMAGE "" -!define HEADERIMAGE "" -!define MAINBINARYNAME "jan_mainbinaryname" -!define MAINBINARYSRCPATH "D:\a\jan\jan\src-tauri\target\release\jan_mainbinaryname.exe" -!define BUNDLEID "jan_mainbinaryname.ai.app" -!define COPYRIGHT "" -!define OUTFILE "nsis-output.exe" -!define ARCH "x64" -!define ADDITIONALPLUGINSPATH "D:\a\jan\jan\src-tauri\target\release\nsis\x64\Plugins\x86-unicode\additional" -!define ALLOWDOWNGRADES "true" -!define DISPLAYLANGUAGESELECTOR "false" -!define INSTALLWEBVIEW2MODE "downloadBootstrapper" -!define WEBVIEW2INSTALLERARGS "/silent" -!define WEBVIEW2BOOTSTRAPPERPATH "" -!define WEBVIEW2INSTALLERPATH "" -!define MINIMUMWEBVIEW2VERSION "" -!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}" -!define MANUKEY "Software\${MANUFACTURER}" -!define MANUPRODUCTKEY "${MANUKEY}\${PRODUCTNAME}" -!define UNINSTALLERSIGNCOMMAND "$\"powershell$\" $\"-ExecutionPolicy$\" $\"Bypass$\" $\"-File$\" $\"./sign.ps1$\" $\"%1$\"" -!define ESTIMATEDSIZE "793795" -!define STARTMENUFOLDER "" -!define VCREDIST_URL "https://aka.ms/vs/17/release/vc_redist.x64.exe" -!define VCREDIST_FILENAME "vc_redist.x64.exe" - -Var PassiveMode -Var UpdateMode -Var NoShortcutMode -Var WixMode -Var OldMainBinaryName - -Name "${PRODUCTNAME}" -BrandingText "${COPYRIGHT}" -OutFile "${OUTFILE}" - -ShowInstDetails nevershow -ShowUninstDetails nevershow - -; We don't actually use this value as default install path, -; it's just for nsis to append the product name folder in the directory selector -; https://nsis.sourceforge.io/Reference/InstallDir -!define PLACEHOLDER_INSTALL_DIR "placeholder\${PRODUCTNAME}" -InstallDir "${PLACEHOLDER_INSTALL_DIR}" - -VIProductVersion "${VERSIONWITHBUILD}" -VIAddVersionKey "ProductName" "${PRODUCTNAME}" -VIAddVersionKey "FileDescription" "${PRODUCTNAME}" -VIAddVersionKey "LegalCopyright" "${COPYRIGHT}" -VIAddVersionKey "FileVersion" "${VERSION}" -VIAddVersionKey "ProductVersion" "${VERSION}" - -# additional plugins -!addplugindir "${ADDITIONALPLUGINSPATH}" - -; Uninstaller signing command -!if "${UNINSTALLERSIGNCOMMAND}" != "" - !uninstfinalize '${UNINSTALLERSIGNCOMMAND}' -!endif - -; Handle install mode, `perUser`, `perMachine` or `both` -!if "${INSTALLMODE}" == "perMachine" - RequestExecutionLevel highest -!endif - -!if "${INSTALLMODE}" == "currentUser" - RequestExecutionLevel user -!endif - -!if "${INSTALLMODE}" == "both" - !define MULTIUSER_MUI - !define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCTNAME}" - !define MULTIUSER_INSTALLMODE_COMMANDLINE - !if "${ARCH}" == "x64" - !define MULTIUSER_USE_PROGRAMFILES64 - !else if "${ARCH}" == "arm64" - !define MULTIUSER_USE_PROGRAMFILES64 - !endif - !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}" - !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser" - !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME - !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation - !define MULTIUSER_EXECUTIONLEVEL Highest - !include MultiUser.nsh -!endif - -; Installer icon -!if "${INSTALLERICON}" != "" - !define MUI_ICON "${INSTALLERICON}" -!endif - -; Installer sidebar image -!if "${SIDEBARIMAGE}" != "" - !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}" -!endif - -; Installer header image -!if "${HEADERIMAGE}" != "" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "${HEADERIMAGE}" -!endif - -; Define registry key to store installer language -!define MUI_LANGDLL_REGISTRY_ROOT "HKCU" -!define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}" -!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" - -; Installer pages, must be ordered as they appear -; 1. Welcome Page -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!insertmacro MUI_PAGE_WELCOME - -; 2. License Page (if defined) -!if "${LICENSE}" != "" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !insertmacro MUI_PAGE_LICENSE "${LICENSE}" -!endif - -; 3. Install mode (if it is set to `both`) -!if "${INSTALLMODE}" == "both" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !insertmacro MULTIUSER_PAGE_INSTALLMODE -!endif - -; 4. Custom page to ask user if he wants to reinstall/uninstall -; only if a previous installation was detected -Var ReinstallPageCheck -Page custom PageReinstall PageLeaveReinstall -Function PageReinstall - ; Uninstall previous WiX installation if exists. - ; - ; A WiX installer stores the installation info in registry - ; using a UUID and so we have to loop through all keys under - ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall` - ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER} - ; - ; This has a potential issue that there maybe another installation that matches - ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer, - ; however, this should be fine since the user will have to confirm the uninstallation - ; and they can chose to abort it if doesn't make sense. - StrCpy $0 0 - wix_loop: - EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0 - StrCmp $1 "" wix_loop_done ; Exit loop if there is no more keys to loop on - IntOp $0 $0 + 1 - ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName" - ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher" - StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop - ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString" - ${StrCase} $R1 $R0 "L" - ${StrLoc} $R0 $R1 "msiexec" ">" - StrCmp $R0 0 0 wix_loop_done - StrCpy $WixMode 1 - StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" - Goto compare_version - wix_loop_done: - - ; Check if there is an existing installation, if not, abort the reinstall page - ReadRegStr $R0 SHCTX "${UNINSTKEY}" "" - ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" - ${IfThen} "$R0$R1" == "" ${|} Abort ${|} - - ; Compare this installar version with the existing installation - ; and modify the messages presented to the user accordingly - compare_version: - StrCpy $R4 "$(older)" - ${If} $WixMode = 1 - ReadRegStr $R0 HKLM "$R6" "DisplayVersion" - ${Else} - ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion" - ${EndIf} - ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|} - - nsis_tauri_utils::SemverCompare "${VERSION}" $R0 - Pop $R0 - ; Reinstalling the same version - ${If} $R0 = 0 - StrCpy $R1 "$(alreadyInstalledLong)" - StrCpy $R2 "$(addOrReinstall)" - StrCpy $R3 "$(uninstallApp)" - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)" - ; Upgrading - ${ElseIf} $R0 = 1 - StrCpy $R1 "$(olderOrUnknownVersionInstalled)" - StrCpy $R2 "$(uninstallBeforeInstalling)" - StrCpy $R3 "$(dontUninstall)" - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" - ; Downgrading - ${ElseIf} $R0 = -1 - StrCpy $R1 "$(newerVersionInstalled)" - StrCpy $R2 "$(uninstallBeforeInstalling)" - !if "${ALLOWDOWNGRADES}" == "true" - StrCpy $R3 "$(dontUninstall)" - !else - StrCpy $R3 "$(dontUninstallDowngrade)" - !endif - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" - ${Else} - Abort - ${EndIf} - - ; Skip showing the page if passive - ; - ; Note that we don't call this earlier at the begining - ; of this function because we need to populate some variables - ; related to current installed version if detected and whether - ; we are downgrading or not. - ${If} $PassiveMode = 1 - Call PageLeaveReinstall - ${Else} - nsDialogs::Create 1018 - Pop $R4 - ${IfThen} $(^RTL) = 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} - - ${NSD_CreateLabel} 0 0 100% 24u $R1 - Pop $R1 - - ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2 - Pop $R2 - ${NSD_OnClick} $R2 PageReinstallUpdateSelection - - ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3 - Pop $R3 - ; Disable this radio button if downgrading and downgrades are disabled - !if "${ALLOWDOWNGRADES}" == "false" - ${IfThen} $R0 = -1 ${|} EnableWindow $R3 0 ${|} - !endif - ${NSD_OnClick} $R3 PageReinstallUpdateSelection - - ; Check the first radio button if this the first time - ; we enter this page or if the second button wasn't - ; selected the last time we were on this page - ${If} $ReinstallPageCheck <> 2 - SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 - ${Else} - SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 - ${EndIf} - - ${NSD_SetFocus} $R2 - nsDialogs::Show - ${EndIf} -FunctionEnd -Function PageReinstallUpdateSelection - ${NSD_GetState} $R2 $R1 - ${If} $R1 == ${BST_CHECKED} - StrCpy $ReinstallPageCheck 1 - ${Else} - StrCpy $ReinstallPageCheck 2 - ${EndIf} -FunctionEnd -Function PageLeaveReinstall - ; In passive mode, always uninstall when upgrading - ${If} $PassiveMode = 1 - ${AndIf} $R0 = 1 ; Upgrading - Goto reinst_uninstall - ${EndIf} - - ${NSD_GetState} $R2 $R1 - - ; If migrating from Wix, always uninstall - ${If} $WixMode = 1 - Goto reinst_uninstall - ${EndIf} - - ; In update mode, always proceeds without uninstalling - ${If} $UpdateMode = 1 - Goto reinst_done - ${EndIf} - - ; $R0 holds whether same(0)/upgrading(1)/downgrading(-1) version - ; $R1 holds the radio buttons state: - ; 1 => first choice was selected - ; 0 => second choice was selected - ${If} $R0 = 0 ; Same version, proceed - ${If} $R1 = 1 ; User chose to add/reinstall - Goto reinst_done - ${Else} ; User chose to uninstall - Goto reinst_uninstall - ${EndIf} - ${ElseIf} $R0 = 1 ; Upgrading - ${If} $R1 = 1 ; User chose to uninstall - Goto reinst_uninstall - ${Else} - Goto reinst_done ; User chose NOT to uninstall - ${EndIf} - ${ElseIf} $R0 = -1 ; Downgrading - ${If} $R1 = 1 ; User chose to uninstall - Goto reinst_uninstall - ${Else} - Goto reinst_done ; User chose NOT to uninstall - ${EndIf} - ${EndIf} - - reinst_uninstall: - HideWindow - ClearErrors - - ${If} $WixMode = 1 - ReadRegStr $R1 HKLM "$R6" "UninstallString" - ExecWait '$R1' $0 - ${Else} - ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" - ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" - ${IfThen} $UpdateMode = 1 ${|} StrCpy $R1 "$R1 /UPDATE" ${|} ; append /UPDATE - ${IfThen} $PassiveMode = 1 ${|} StrCpy $R1 "$R1 /P" ${|} ; append /P - StrCpy $R1 "$R1 _?=$4" ; append uninstall directory - ExecWait '$R1' $0 - ${EndIf} - - BringToFront - - ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code - - ${If} $0 <> 0 - ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe" - ; User cancelled wix uninstaller? return to select un/reinstall page - ${If} $WixMode = 1 - ${AndIf} $0 = 1602 - Abort - ${EndIf} - - ; User cancelled NSIS uninstaller? return to select un/reinstall page - ${If} $0 = 1 - Abort - ${EndIf} - - ; Other erros? show generic error message and return to select un/reinstall page - MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)" - Abort - ${EndIf} - reinst_done: -FunctionEnd - -; 5. Choose install directory page -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!insertmacro MUI_PAGE_DIRECTORY - -; 6. Start menu shortcut page -Var AppStartMenuFolder -!if "${STARTMENUFOLDER}" != "" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${STARTMENUFOLDER}" -!else - !define MUI_PAGE_CUSTOMFUNCTION_PRE Skip -!endif -!insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder - -; 7. Installation page -!insertmacro MUI_PAGE_INSTFILES - -; 8. Finish page -; -; Don't auto jump to finish page after installation page, -; because the installation page has useful info that can be used debug any issues with the installer. -!define MUI_FINISHPAGE_NOAUTOCLOSE -; Use show readme button in the finish page as a button create a desktop shortcut -!define MUI_FINISHPAGE_SHOWREADME -!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(createDesktop)" -!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateOrUpdateDesktopShortcut -; Show run app after installation. -!define MUI_FINISHPAGE_RUN -!define MUI_FINISHPAGE_RUN_FUNCTION RunMainBinary -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!insertmacro MUI_PAGE_FINISH - -Function RunMainBinary - nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "" -FunctionEnd - -; Uninstaller Pages -; 1. Confirm uninstall page -Var DeleteAppDataCheckbox -Var DeleteAppDataCheckboxState -!define /ifndef WS_EX_LAYOUTRTL 0x00400000 -!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow -Function un.ConfirmShow ; Add add a `Delete app data` check box - ; $1 inner dialog HWND - ; $2 window DPI - ; $3 style - ; $4 x - ; $5 y - ; $6 width - ; $7 height - FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog - System::Call "user32::GetDpiForWindow(p r1) i .r2" - ${If} $(^RTL) = 1 - StrCpy $3 "${__NSD_CheckBox_EXSTYLE} | ${WS_EX_LAYOUTRTL}" - IntOp $4 50 * $2 - ${Else} - StrCpy $3 "${__NSD_CheckBox_EXSTYLE}" - IntOp $4 0 * $2 - ${EndIf} - IntOp $5 100 * $2 - IntOp $6 400 * $2 - IntOp $7 25 * $2 - IntOp $4 $4 / 96 - IntOp $5 $5 / 96 - IntOp $6 $6 / 96 - IntOp $7 $7 / 96 - System::Call 'user32::CreateWindowEx(i r3, w "${__NSD_CheckBox_CLASS}", w "$(deleteAppData)", i ${__NSD_CheckBox_STYLE}, i r4, i r5, i r6, i r7, p r1, i0, i0, i0) i .s' - Pop $DeleteAppDataCheckbox - SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1 - SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1 -FunctionEnd -!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave -Function un.ConfirmLeave - SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState -FunctionEnd -!define MUI_PAGE_CUSTOMFUNCTION_PRE un.SkipIfPassive -!insertmacro MUI_UNPAGE_CONFIRM - -; 2. Uninstalling Page -!insertmacro MUI_UNPAGE_INSTFILES - -;Languages -!insertmacro MUI_LANGUAGE "English" -!insertmacro MUI_RESERVEFILE_LANGDLL - !include "D:\a\jan\jan\src-tauri\target\release\nsis\x64\English.nsh" - -Function .onInit - ${GetOptions} $CMDLINE "/P" $PassiveMode - ${IfNot} ${Errors} - StrCpy $PassiveMode 1 - ${EndIf} - ; always run in passive mode - StrCpy $PassiveMode 1 - - ${GetOptions} $CMDLINE "/NS" $NoShortcutMode - ${IfNot} ${Errors} - StrCpy $NoShortcutMode 1 - ${EndIf} - - ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode - ${IfNot} ${Errors} - StrCpy $UpdateMode 1 - ${EndIf} - - !if "${DISPLAYLANGUAGESELECTOR}" == "true" - !insertmacro MUI_LANGDLL_DISPLAY - !endif - - !insertmacro SetContext - - ${If} $INSTDIR == "${PLACEHOLDER_INSTALL_DIR}" - ; Set default install location - !if "${INSTALLMODE}" == "perMachine" - ${If} ${RunningX64} - !if "${ARCH}" == "x64" - StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}" - !else if "${ARCH}" == "arm64" - StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}" - !else - StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}" - !endif - ${Else} - StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}" - ${EndIf} - !else if "${INSTALLMODE}" == "currentUser" - StrCpy $INSTDIR "$LOCALAPPDATA\Programs\${PRODUCTNAME}" - !endif - - Call RestorePreviousInstallLocation - ${EndIf} - - ; Remove old Jan if it exists - ${If} ${FileExists} "$INSTDIR\LICENSE.electron.txt" - DeleteRegKey HKLM "Software\${PRODUCTNAME}" - RMDir /r "$INSTDIR" - Delete "$INSTDIR\*.*" - ${EndIf} - - !if "${INSTALLMODE}" == "both" - !insertmacro MULTIUSER_INIT - !endif -FunctionEnd - - -Section EarlyChecks - ; Abort silent installer if downgrades is disabled - !if "${ALLOWDOWNGRADES}" == "false" - ${If} ${Silent} - ; If downgrading - ${If} $R0 = -1 - System::Call 'kernel32::AttachConsole(i -1)i.r0' - ${If} $0 <> 0 - System::Call 'kernel32::GetStdHandle(i -11)i.r0' - System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color - FileWrite $0 "$(silentDowngrades)" - ${EndIf} - Abort - ${EndIf} - ${EndIf} - !endif - -SectionEnd - -Section WebView2 - ; Check if Webview2 is already installed and skip this section - ${If} ${RunningX64} - ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" - ${Else} - ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" - ${EndIf} - ${If} $4 == "" - ReadRegStr $4 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\${WEBVIEW2APPGUID}" "pv" - ${EndIf} - - ${If} $4 == "" - ; Webview2 installation - ; - ; Skip if updating - ${If} $UpdateMode <> 1 - !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper" - Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" - DetailPrint "$(webview2Downloading)" - NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Pop $0 - ${If} $0 == "success" - DetailPrint "$(webview2DownloadSuccess)" - ${Else} - DetailPrint "$(webview2DownloadError)" - Abort "$(webview2AbortError)" - ${EndIf} - StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Goto install_webview2 - !endif - - !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper" - Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" - File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}" - DetailPrint "$(installingWebview2)" - StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Goto install_webview2 - !endif - - !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller" - Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" - File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}" - DetailPrint "$(installingWebview2)" - StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" - Goto install_webview2 - !endif - - Goto webview2_done - - install_webview2: - DetailPrint "$(installingWebview2)" - ; $6 holds the path to the webview2 installer - ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1 - ${If} $1 = 0 - DetailPrint "$(webview2InstallSuccess)" - ${Else} - DetailPrint "$(webview2InstallError)" - Abort "$(webview2AbortError)" - ${EndIf} - webview2_done: - ${EndIf} - ${Else} - !if "${MINIMUMWEBVIEW2VERSION}" != "" - ${VersionCompare} "${MINIMUMWEBVIEW2VERSION}" "$4" $R0 - ${If} $R0 = 1 - update_webview: - DetailPrint "$(installingWebview2)" - ${If} ${RunningX64} - ReadRegStr $R1 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate" "path" - ${Else} - ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\EdgeUpdate" "path" - ${EndIf} - ${If} $R1 == "" - ReadRegStr $R1 HKCU "SOFTWARE\Microsoft\EdgeUpdate" "path" - ${EndIf} - ${If} $R1 != "" - ; Chromium updater docs: https://source.chromium.org/chromium/chromium/src/+/main:docs/updater/user_manual.md - ; Modified from "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft EdgeWebView\ModifyPath" - ExecWait `"$R1" /install appguid=${WEBVIEW2APPGUID}&needsadmin=true` $1 - ${If} $1 = 0 - DetailPrint "$(webview2InstallSuccess)" - ${Else} - MessageBox MB_ICONEXCLAMATION|MB_ABORTRETRYIGNORE "$(webview2InstallError)" IDIGNORE ignore IDRETRY update_webview - Quit - ignore: - ${EndIf} - ${EndIf} - ${EndIf} - !endif - ${EndIf} -SectionEnd - -Section VCRedist - ; Check if VC++ Redistributable is already installed - ; Check for Visual Studio 2015-2022 redistributable (14.0 or higher) - ReadRegStr $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Version" - ${If} $0 == "" - ; Try alternative registry location - ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Version" - ${EndIf} - ${If} $0 == "" - ; Try checking for any version of Visual C++ 2015-2022 Redistributable - ReadRegStr $0 HKLM "SOFTWARE\Classes\Installer\Dependencies\Microsoft.VS.VC_RuntimeMinimumVSU_amd64,v14" "Version" - ${EndIf} - - ${If} $0 == "" - ; VC++ Redistributable not found, need to install - DetailPrint "Visual C++ Redistributable not found, downloading and installing..." - - ; Download VC++ Redistributable - Delete "$TEMP\${VCREDIST_FILENAME}" - DetailPrint "Downloading Visual C++ Redistributable..." - NSISdl::download "${VCREDIST_URL}" "$TEMP\${VCREDIST_FILENAME}" - Pop $1 - - ${If} $1 == "success" - DetailPrint "Visual C++ Redistributable download successful" - - ; Install VC++ Redistributable silently - DetailPrint "Installing Visual C++ Redistributable..." - ExecWait '"$TEMP\${VCREDIST_FILENAME}" /quiet /norestart' $2 - - ${If} $2 == 0 - DetailPrint "Visual C++ Redistributable installed successfully" - ${ElseIf} $2 == 1638 - DetailPrint "Visual C++ Redistributable already installed (newer version)" - ${ElseIf} $2 == 3010 - DetailPrint "Visual C++ Redistributable installed successfully (restart required)" - ; You might want to handle restart requirement here - ${Else} - DetailPrint "Visual C++ Redistributable installation failed with exit code: $2" - MessageBox MB_ICONEXCLAMATION|MB_YESNO "Visual C++ Redistributable installation failed. Continue anyway?" IDYES continue_install - Abort "Installation cancelled due to Visual C++ Redistributable failure" - continue_install: - ${EndIf} - - ; Clean up downloaded file - Delete "$TEMP\${VCREDIST_FILENAME}" - ${Else} - DetailPrint "Failed to download Visual C++ Redistributable: $1" - MessageBox MB_ICONEXCLAMATION|MB_YESNO "Failed to download Visual C++ Redistributable. Continue anyway?" IDYES continue_install_download_fail - Abort "Installation cancelled due to download failure" - continue_install_download_fail: - ${EndIf} - ${Else} - DetailPrint "Visual C++ Redistributable already installed (version: $0)" - ${EndIf} -SectionEnd - -Section Install - SetDetailsPrint none - SetOutPath $INSTDIR - - !ifmacrodef NSIS_HOOK_PREINSTALL - !insertmacro NSIS_HOOK_PREINSTALL - !endif - - !insertmacro CheckIfAppIsRunning "${MAINBINARYNAME}.exe" "${PRODUCTNAME}" - - ; Copy main executable - File "${MAINBINARYSRCPATH}" - - ; Copy resources - CreateDirectory "$INSTDIR\resources" - CreateDirectory "$INSTDIR\resources\pre-install" - SetOutPath $INSTDIR - File /a "/oname=vulkan-1.dll" "D:\a\jan\jan\src-tauri\resources\lib\vulkan-1.dll" - File /a "/oname=LICENSE" "D:\a\jan\jan\src-tauri\resources\LICENSE" - SetOutPath "$INSTDIR\resources\pre-install" - File /nonfatal /a /r "D:\a\jan\jan\src-tauri\resources\pre-install\" - SetOutPath $INSTDIR - - ; Copy external binaries - File /a "/oname=bun.exe" "D:\a\jan\jan\src-tauri\resources\bin\bun-x86_64-pc-windows-msvc.exe" - File /a "/oname=uv.exe" "D:\a\jan\jan\src-tauri\resources\bin\uv-x86_64-pc-windows-msvc.exe" - - ; Create file associations - - ; Register deep links - - ; Create uninstaller - WriteUninstaller "$INSTDIR\uninstall.exe" - - ; Save $INSTDIR in registry for future installations - WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR - - !if "${INSTALLMODE}" == "both" - ; Save install mode to be selected by default for the next installation such as updating - ; or when uninstalling - WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1 - !endif - - ; Remove old main binary if it doesn't match new main binary name - ReadRegStr $OldMainBinaryName SHCTX "${UNINSTKEY}" "MainBinaryName" - ${If} $OldMainBinaryName != "" - ${AndIf} $OldMainBinaryName != "${MAINBINARYNAME}.exe" - Delete "$INSTDIR\$OldMainBinaryName" - ${EndIf} - - ; Save current MAINBINARYNAME for future updates - WriteRegStr SHCTX "${UNINSTKEY}" "MainBinaryName" "${MAINBINARYNAME}.exe" - - ; Registry information for add/remove programs - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}" - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}" - WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}" - WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\"" - WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1" - WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1" - - ${GetSize} "$INSTDIR" "/M=uninstall.exe /S=0K /G=0" $0 $1 $2 - IntOp $0 $0 + ${ESTIMATEDSIZE} - IntFmt $0 "0x%08X" $0 - WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "$0" - - !if "${HOMEPAGE}" != "" - WriteRegStr SHCTX "${UNINSTKEY}" "URLInfoAbout" "${HOMEPAGE}" - WriteRegStr SHCTX "${UNINSTKEY}" "URLUpdateInfo" "${HOMEPAGE}" - WriteRegStr SHCTX "${UNINSTKEY}" "HelpLink" "${HOMEPAGE}" - !endif - - ; Create start menu shortcut - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - Call CreateOrUpdateStartMenuShortcut - !insertmacro MUI_STARTMENU_WRITE_END - - ; Create desktop shortcut for silent and passive installers - ; because finish page will be skipped - ${If} $PassiveMode = 1 - ${OrIf} ${Silent} - Call CreateOrUpdateDesktopShortcut - ${EndIf} - - !ifmacrodef NSIS_HOOK_POSTINSTALL - !insertmacro NSIS_HOOK_POSTINSTALL - !endif - - ; Auto close this page for passive mode - ${If} $PassiveMode = 1 - SetAutoClose true - ${EndIf} -SectionEnd - -Function .onInstSuccess - ; Check for `/R` flag only in silent and passive installers because - ; GUI installer has a toggle for the user to (re)start the app - ${If} $PassiveMode = 1 - ${OrIf} ${Silent} - ; ${GetOptions} $CMDLINE "/R" $R0 - ; ${IfNot} ${Errors} - ${GetOptions} $CMDLINE "/ARGS" $R0 - nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "$R0" - ; ${EndIf} - ${EndIf} -FunctionEnd - -Function un.onInit - !insertmacro SetContext - - !if "${INSTALLMODE}" == "both" - !insertmacro MULTIUSER_UNINIT - !endif - - !insertmacro MUI_UNGETLANGUAGE - - ${GetOptions} $CMDLINE "/P" $PassiveMode - ${IfNot} ${Errors} - StrCpy $PassiveMode 1 - ${EndIf} - - ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode - ${IfNot} ${Errors} - StrCpy $UpdateMode 1 - ${EndIf} -FunctionEnd - -Section Uninstall - SetDetailsPrint none - - !ifmacrodef NSIS_HOOK_PREUNINSTALL - !insertmacro NSIS_HOOK_PREUNINSTALL - !endif - - !insertmacro CheckIfAppIsRunning "${MAINBINARYNAME}.exe" "${PRODUCTNAME}" - - ; Delete the app directory and its content from disk - ; Copy main executable - Delete "$INSTDIR\${MAINBINARYNAME}.exe" - - ; Delete LICENSE file - Delete "$INSTDIR\LICENSE" - - ; Delete resources - Delete "$INSTDIR\resources\pre-install\janhq-assistant-extension-1.0.2.tgz" - Delete "$INSTDIR\resources\pre-install\janhq-conversational-extension-1.0.0.tgz" - Delete "$INSTDIR\resources\pre-install\janhq-engine-management-extension-1.0.3.tgz" - Delete "$INSTDIR\resources\pre-install\janhq-hardware-management-extension-1.0.0.tgz" - Delete "$INSTDIR\resources\pre-install\janhq-inference-cortex-extension-1.0.25.tgz" - Delete "$INSTDIR\resources\pre-install\janhq-model-extension-1.0.36.tgz" - - ; Delete external binaries - Delete "$INSTDIR\bun.exe" - Delete "$INSTDIR\uv.exe" - - ; Delete app associations - - ; Delete deep links - - - ; Delete uninstaller - Delete "$INSTDIR\uninstall.exe" - - RMDir /REBOOTOK "$INSTDIR\resources\pre-install" - RMDir /r /REBOOTOK "$INSTDIR\resources" - RMDir /r "$INSTDIR" - - ; Remove shortcuts if not updating - ${If} $UpdateMode <> 1 - !insertmacro DeleteAppUserModelId - - ; Remove start menu shortcut - !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder - !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - Delete "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - RMDir "$SMPROGRAMS\$AppStartMenuFolder" - ${EndIf} - !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" - Delete "$SMPROGRAMS\${PRODUCTNAME}.lnk" - ${EndIf} - - ; Remove desktop shortcuts - !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$DESKTOP\${PRODUCTNAME}.lnk" - Delete "$DESKTOP\${PRODUCTNAME}.lnk" - ${EndIf} - ${EndIf} - - ; Remove registry information for add/remove programs - !if "${INSTALLMODE}" == "both" - DeleteRegKey SHCTX "${UNINSTKEY}" - !else if "${INSTALLMODE}" == "perMachine" - DeleteRegKey HKLM "${UNINSTKEY}" - !else - DeleteRegKey HKCU "${UNINSTKEY}" - !endif - - ; Removes the Autostart entry for ${PRODUCTNAME} from the HKCU Run key if it exists. - ; This ensures the program does not launch automatically after uninstallation if it exists. - ; If it doesn't exist, it does nothing. - ; We do this when not updating (to preserve the registry value on updates) - ${If} $UpdateMode <> 1 - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${PRODUCTNAME}" - ${EndIf} - - ; Delete app data if the checkbox is selected - ; and if not updating - ${If} $DeleteAppDataCheckboxState = 1 - ${AndIf} $UpdateMode <> 1 - ; Clear the install location $INSTDIR from registry - DeleteRegKey SHCTX "${MANUPRODUCTKEY}" - DeleteRegKey /ifempty SHCTX "${MANUKEY}" - - ; Clear the install language from registry - DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language" - DeleteRegKey /ifempty HKCU "${MANUPRODUCTKEY}" - DeleteRegKey /ifempty HKCU "${MANUKEY}" - - SetShellVarContext current - RmDir /r "$APPDATA\${BUNDLEID}" - RmDir /r "$LOCALAPPDATA\${BUNDLEID}" - ${EndIf} - - !ifmacrodef NSIS_HOOK_POSTUNINSTALL - !insertmacro NSIS_HOOK_POSTUNINSTALL - !endif - - ; Auto close if passive mode or updating - ${If} $PassiveMode = 1 - ${OrIf} $UpdateMode = 1 - SetAutoClose true - ${EndIf} -SectionEnd - -Function RestorePreviousInstallLocation - ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" - StrCmp $4 "" +2 0 - StrCpy $INSTDIR $4 -FunctionEnd - -Function Skip - Abort -FunctionEnd - -Function SkipIfPassive - ${IfThen} $PassiveMode = 1 ${|} Abort ${|} -FunctionEnd -Function un.SkipIfPassive - ${IfThen} $PassiveMode = 1 ${|} Abort ${|} -FunctionEnd - -Function CreateOrUpdateStartMenuShortcut - ; We used to use product name as MAINBINARYNAME - ; migrate old shortcuts to target the new MAINBINARYNAME - StrCpy $R0 0 - - !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - StrCpy $R0 1 - ${EndIf} - - !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - StrCpy $R0 1 - ${EndIf} - - ${If} $R0 = 1 - Return - ${EndIf} - - ; Skip creating shortcut if in update mode or no shortcut mode - ; but always create if migrating from wix - ${If} $WixMode = 0 - ${If} $UpdateMode = 1 - ${OrIf} $NoShortcutMode = 1 - Return - ${EndIf} - ${EndIf} - - !if "${STARTMENUFOLDER}" != "" - CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder" - CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - !else - CreateShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\${PRODUCTNAME}.lnk" - !endif -FunctionEnd - -Function CreateOrUpdateDesktopShortcut - ; We used to use product name as MAINBINARYNAME - ; migrate old shortcuts to target the new MAINBINARYNAME - !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\$OldMainBinaryName" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Return - ${EndIf} - - ; Skip creating shortcut if in update mode or no shortcut mode - ; but always create if migrating from wix - ${If} $WixMode = 0 - ${If} $UpdateMode = 1 - ${OrIf} $NoShortcutMode = 1 - Return - ${EndIf} - ${EndIf} - - CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk" -FunctionEnd \ No newline at end of file