#define APPNAM "ZoiteChat" #define APPVER "<#= [string]::Join('.', $versionParts) #>" ; ---- ARM64 build defaults (override via ISCC /D...) ---- #ifndef APPARCH #define APPARCH "arm64" #endif #ifndef PROJECTDIR ; Folder containing wizardimage.bmp / wizardsmallimage.bmp #define PROJECTDIR "C:\...\zoitechat\win32\installer\" #endif #ifndef SRCDIR ; Root of your staged tree (must contain bin\, lib\, share\, etc\) ; In your workflow this is typically: \dist #define SRCDIR "..\dist" #endif ; Inno Download Plugin (kept for consistency) #include [Setup] AppName={#APPNAM} AppVersion={#APPVER} AppVerName={#APPNAM} {#APPVER} AppPublisher=ZoiteChat AppPublisherURL=http://zoitechat.zoite.net AppCopyright=Copyright (C) 1998-2010 Peter Zelezny AppSupportURL=https://github.com/zoitechat/zoitechat/issues AppUpdatesURL=http://zoitechat.zoite.net/downloads.html LicenseFile=share\doc\zoitechat\COPYING UninstallDisplayIcon={app}\zoitechat.exe UninstallDisplayName={#APPNAM} ; ARM64 = 64-bit Program Files DefaultDirName={pf64}\ZoiteChat DefaultGroupName={#APPNAM} AllowNoIcons=yes SolidCompression=yes Compression=lzma2/ultra64 ; Pull files from staged tree (MSYS2 dist) SourceDir={#SRCDIR} OutputDir=.. OutputBaseFilename={#APPNAM}-{#APPVER}_arm64 FlatComponentsList=no PrivilegesRequired=none ShowComponentSizes=no CreateUninstallRegKey=not IsTaskSelected('portable') Uninstallable=not IsTaskSelected('portable') ; ARM64-only installer ArchitecturesAllowed=arm64 ArchitecturesInstallIn64BitMode=arm64 ; You can keep 6.1, but ARM64 Windows is realistically 10+. MinVersion=10.0 WizardImageFile={#PROJECTDIR}wizardimage.bmp WizardSmallImageFile={#PROJECTDIR}wizardsmallimage.bmp SetupIconFile={#PROJECTDIR}..\..\data\icons\zoitechat.ico [Types] Name: "normal"; Description: "Normal Installation" Name: "minimal"; Description: "Minimal Installation" Name: "custom"; Description: "Custom Installation"; Flags: iscustom [Components] Name: "libs"; Description: "ZoiteChat"; Types: normal minimal custom; Flags: fixed Name: "xctext"; Description: "ZoiteChat-Text"; Types: custom; Flags: disablenouninstallwarning Name: "xtm"; Description: "ZoiteChat Theme Manager"; Types: normal custom; Flags: disablenouninstallwarning Name: "icons"; Description: "Create Shortcuts"; Types: custom; Flags: disablenouninstallwarning Name: "icons\desktopicon"; Description: "Create Desktop Shortcut"; Types: custom; Flags: disablenouninstallwarning Name: "icons\quicklaunchicon"; Description: "Create Quick Launch Shortcut"; Types: custom; Flags: disablenouninstallwarning Name: "translations"; Description: "Translations"; Types: normal custom; Flags: disablenouninstallwarning Name: "spell"; Description: "Spelling Dictionaries"; Types: custom; Flags: disablenouninstallwarning Name: "plugins"; Description: "Plugins"; Types: custom; Flags: disablenouninstallwarning Name: "plugins\checksum"; Description: "Checksum"; Types: custom; Flags: disablenouninstallwarning Name: "plugins\exec"; Description: "Exec"; Types: custom; Flags: disablenouninstallwarning Name: "plugins\fishlim"; Description: "FiSHLiM"; Types: custom; Flags: disablenouninstallwarning Name: "plugins\sysinfo"; Description: "SysInfo"; Types: custom; Flags: disablenouninstallwarning Name: "plugins\upd"; Description: "Update Checker"; Types: normal custom; Flags: disablenouninstallwarning Name: "plugins\winamp"; Description: "Winamp"; Types: custom; Flags: disablenouninstallwarning Name: "langs"; Description: "Language Interfaces"; Types: custom; Flags: disablenouninstallwarning Name: "langs\lua"; Description: "Lua"; Types: normal custom; Flags: disablenouninstallwarning ; These are kept for consistency, but hidden on ARM64 unless you later ship ARM64 installers for them. Name: "langs\perl"; Description: "Perl (requires Perl 5.20)"; Types: custom; Flags: disablenouninstallwarning; Check: not IsArm64 Name: "langs\python"; Description: "Python (requires Python 3.8)"; Types: custom; Flags: disablenouninstallwarning; Check: not IsArm64 [Tasks] Name: portable; Description: "Yes"; GroupDescription: "Portable Mode: Stores configuration files within install directory for portable drives."; Flags: unchecked [Registry] Root: HKCR; Subkey: "irc"; ValueType: none; ValueName: ""; ValueData: ""; Flags: deletekey uninsdeletekey; Tasks: not portable Root: HKCR; Subkey: "irc"; ValueType: string; ValueName: ""; ValueData: "URL:IRC Protocol"; Flags: uninsdeletevalue; Tasks: not portable Root: HKCR; Subkey: "irc"; ValueType: string; ValueName: "URL Protocol"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable Root: HKCR; Subkey: "irc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\zoitechat.exe,0"; Flags: uninsdeletevalue; Tasks: not portable Root: HKCR; Subkey: "irc\shell"; ValueType: string; ValueName: ""; ValueData: "open"; Flags: uninsdeletevalue; Tasks: not portable Root: HKCR; Subkey: "irc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\zoitechat.exe --url=""%1"""; Flags: uninsdeletevalue; Tasks: not portable Root: HKCR; Subkey: ".hct"; ValueType: none; ValueName: ""; ValueData: ""; Flags: deletekey uninsdeletekey; Components:xtm; Tasks: not portable Root: HKCR; Subkey: ".hct"; ValueType: string; ValueName: ""; ValueData: "ZoiteChat Theme File"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable Root: HKCR; Subkey: ".hct"; ValueType: string; ValueName: "ZoiteChat Theme File"; ValueData: ""; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable Root: HKCR; Subkey: ".hct\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\thememan.exe,0"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable Root: HKCR; Subkey: ".hct\shell"; ValueType: string; ValueName: ""; ValueData: "open"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable Root: HKCR; Subkey: ".hct\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\thememan.exe ""%1"""; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable [Run] Filename: "{app}\zoitechat.exe"; Description: "Run ZoiteChat after closing the Wizard"; Flags: nowait postinstall skipifsilent Filename: "http://docs.zoitechat.org/en/latest/changelog.html"; Description: "See what's changed"; Flags: shellexec runasoriginaluser postinstall skipifsilent unchecked ; VC++ redist (ARM64) Filename: "{tmp}\vcredist.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable"; Flags: skipifdoesntexist; Tasks: not portable ; Old x86/x64 extras intentionally omitted on ARM64 ; (dotnet/perl/python/spelling-dicts) – keep your existing behavior on x86/x64 installers. [Files] ; Portable marker (same behavior) Source: "portable-mode"; DestDir: "{app}"; Tasks: portable; Flags: skipifsourcedoesntexist ; Optional URLs/cert (don’t fail if your dist doesn’t include them) Source: "changelog.url"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: libs Source: "readme.url"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: libs Source: "cert.pem"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: libs ; ---- Core binaries + runtime DLLs ---- ; We install bin\ contents into {app} to match the non-ARM installer layout. Source: "bin\zoitechat.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\zoitechat-text.exe"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: xctext Source: "bin\thememan.exe"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: xtm ; All staged DLLs/helpers shipped alongside the EXE (your CI harvest step should have copied deps into bin\) Source: "bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: libs Source: "bin\gspawn-*.exe"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: libs ; ---- Shared data ---- Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs Source: "share\doc\*"; DestDir: "{app}\share\doc"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs Source: "share\themes\*"; DestDir: "{app}\share\themes"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs ; Translations split out like the original installer Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: translations ; ---- Plugins (staged under lib\zoitechat\plugins\*.dll) ---- ; Map them to {app}\plugins like the existing Windows installs. Source: "lib\zoitechat\plugins\*checksum*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\checksum Source: "lib\zoitechat\plugins\*exec*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\exec Source: "lib\zoitechat\plugins\*fishlim*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\fishlim Source: "lib\zoitechat\plugins\*sysinfo*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\sysinfo Source: "lib\zoitechat\plugins\*upd*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\upd Source: "lib\zoitechat\plugins\*winamp*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: plugins\winamp Source: "lib\zoitechat\plugins\*lua*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: langs\lua ; Python integration (only if you actually stage these on ARM64) Source: "lib\zoitechat\plugins\*python*.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion skipifsourcedoesntexist; Components: langs\python Source: "python\*.py"; DestDir: "{app}\python"; Flags: ignoreversion skipifsourcedoesntexist; Components: langs\python Source: "_cffi_backend.cp3*.pyd"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist; Components: langs\python [Icons] Name: "{group}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "ZoiteChat.Desktop.Notify"; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat Safe Mode"; Filename: "{app}\zoitechat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat Config Folder"; Filename: "%APPDATA%\ZoiteChat\"; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat-Text"; Filename: "{app}\zoitechat-text.exe"; Components: xctext; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\ZoiteChat Theme Manager"; Filename: "{app}\thememan.exe"; Components: xtm; Tasks: not portable; Check: not WizardNoIcons Name: "{group}\Uninstall ZoiteChat"; Filename: "{uninstallexe}"; Tasks: not portable; Check: not WizardNoIcons Name: "{commondesktop}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "ZoiteChat.Desktop.Notify"; Components: icons\desktopicon; Tasks: not portable Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\ZoiteChat"; Filename: "{app}\zoitechat.exe"; Components: icons\quicklaunchicon; Tasks: not portable [Messages] BeveledLabel= {#APPNAM} [Code] procedure InitializeWizard; begin WizardForm.LicenseAcceptedRadio.Checked := True; idpDownloadAfter(wpReady); end; function GetSysDir(): String; begin ; ARM64 is 64-bit, so {sys} is correct Result := ExpandConstant('{sys}\'); end; function CheckVCInstall(): Boolean; begin Result := FileExists(GetSysDir() + 'vcruntime140.dll'); end; procedure CurPageChanged(CurPageID: Integer); var REDIST: String; begin if (CurPageID = wpReady) then begin idpClearFiles; if not IsTaskSelected('portable') then begin ; VC++ 2015-2022 ARM64 redistributable (stable official URL) REDIST := 'https://aka.ms/vs/17/release/vc_redist.arm64.exe'; if not CheckVCInstall() then idpAddFile(REDIST, ExpandConstant('{tmp}\vcredist.exe')); end; end; end; function NextButtonClick(CurPageID: Integer): Boolean; begin if (CurPageID = wpSelectTasks) then if (WizardForm.TasksList.Checked[1] = True) then if (WizardDirValue() = ExpandConstant('{pf64}\ZoiteChat')) then begin WizardForm.TasksList.Checked[1] := False; MsgBox('Portable mode is only intended for use on portable drives and has been disabled.', mbInformation, MB_OK); end; Result := True; end; function GetUninstallString(): String; var sUnInstPath: String; sUnInstallString: String; begin sUnInstallString := ''; ; Prefer ARM64 entry, but also handle migrating from x64/x86 installs on ARM devices. sUnInstPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\ZoiteChat (ARM64)_is1'; if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); if sUnInstallString = '' then begin sUnInstPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\ZoiteChat (x64)_is1'; if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); end; if sUnInstallString = '' then begin sUnInstPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\ZoiteChat (x86)_is1'; if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); end; if sUnInstallString = '' then begin sUnInstPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\ZoiteChat_is1'; if not RegQueryStringValue(HKLM32, sUnInstPath, 'UninstallString', sUnInstallString) then if not RegQueryStringValue(HKCU32, sUnInstPath, 'UninstallString', sUnInstallString) then if IsWin64 then if not RegQueryStringValue(HKLM64, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU64, sUnInstPath, 'UninstallString', sUnInstallString); end; Result := sUnInstallString; end; function IsUpgrade(): Boolean; begin Result := (GetUninstallString() <> ''); end; function UnInstallOldVersion(): Integer; var sUnInstallString: String; iResultCode: Integer; begin Result := 0; sUnInstallString := GetUninstallString(); if sUnInstallString <> '' then begin sUnInstallString := RemoveQuotes(sUnInstallString); if Exec(sUnInstallString, '/VERYSILENT /NORESTART /SUPPRESSMSGBOXES', '', SW_HIDE, ewWaitUntilTerminated, iResultCode) then Result := 3 else Result := 2; end else Result := 1; end; procedure CurStepChanged(CurStep: TSetupStep); begin if not IsTaskSelected('portable') then begin if (CurStep = ssInstall) then begin if IsUpgrade() then UnInstallOldVersion(); DeleteFile(ExpandConstant('{app}\portable-mode')); end; end; end;