| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876 |
- #define AppId "winscp3"
- #define AppMutex "WinSCP"
- #define ParentRegistryKey "Software\Martin Prikryl"
- #define RegistryKey ParentRegistryKey+"\WinSCP 2"
- #define DefaultLang "en"
- #define WebRoot "https://winscp.net/"
- #define WebForum WebRoot+"forum/"
- #define WebDocumentation WebRoot+"eng/docs/"
- #define WebReport "https://winscp.net/install.php"
- #define Year 2019
- #define EnglishLang "English"
- #define SetupTypeData "SetupType"
- #define InnoSetupReg "Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
- #define InnoSetupAppPathReg "Inno Setup: App Path"
- #ifndef CompletenessThreshold
- #define CompletenessThreshold 100
- #else
- #define CompletenessThreshold Int(CompletenessThreshold)
- #endif
- #ifndef InclusionThreshold
- #define InclusionThreshold 100
- #else
- #define InclusionThreshold Int(InclusionThreshold)
- #endif
- #ifndef PuttySourceDir
- #if DirExists("c:\Program Files (x86)\PuTTY")
- #define PuttySourceDir "c:\Program Files (x86)\PuTTY"
- #else
- #define PuttySourceDir "c:\Program Files\PuTTY"
- #endif
- #endif
- #ifndef Status
- #define Status "unofficial"
- #endif
- #ifndef SourceDir
- #define SourceDir "..\source"
- #endif
- #ifndef BinariesDir
- #define BinariesDir SourceDir + "\Win32\Release"
- #endif
- #ifndef BinariesDir64
- #define BinariesDir64 SourceDir + "\Win64\Release"
- #endif
- #ifndef BinariesDirAssembly
- #define BinariesDirAssembly "..\dotnet\Win32\Release"
- #endif
- #ifndef AllTranslations
- #define AllTranslations
- #endif
- #define TranslationDir "translations"
- #define OutputDir "."
- #define TranslationFileMask "WinSCP.???"
- #define MainFileName "WinSCP.exe"
- #define MainFileSource BinariesDir+"\"+MainFileName
- #define ShellExtFileName "DragExt.dll"
- #define ShellExtFileSource BinariesDir+"\"+ShellExtFileName
- #define ShellExt64FileName "DragExt64.dll"
- #define ShellExt64FileSource BinariesDir64+"\"+ShellExt64FileName
- #define ConsoleFileSource BinariesDir+"\WinSCP.com"
- #define MapFileSource BinariesDir+"\WinSCP.map"
- #define AssemblyFileSource BinariesDirAssembly+"\WinSCPnet.dll"
- #ifdef Donations
- #define PayPalCardImage "PayPalCard.bmp"
- #endif
- #define Major
- #define Minor
- #define Rev
- #define Build
- #expr ParseVersion(MainFileSource, Major, Minor, Rev, Build)
- #define VersionOnly Str(Major)+"."+Str(Minor)+(Rev > 0 ? "."+Str(Rev) : "")
- #define Version VersionOnly+(Status != "" ? " "+Status : "")
- #ifndef BaseFilename
- #define FTag VersionOnly+(Status != "" ? "."+Status : "")
- #define BaseFilename "WinSCP-" + FTag + "-Setup"
- #endif
- #define WebArguments "ver=" +VersionOnly + "&lang={language}&utm_source=winscp&utm_medium=setup&utm_campaign=" + VersionOnly
- #define WebGettingStarted WebRoot + "eng/installed.php?" + WebArguments + "&prevver="
- #define MessagesPath(L) TranslationDir + "\" + "WinSCP." + L + ".islu"
- #define ExplorerFileBase "Explorer"
- #define CommanderFileBase "Commander"
- #define SelectDirFileBase "Opened bookmark folder-stored session folder"
- [Setup]
- AppId={#AppId}
- AppName=WinSCP
- AppPublisher=Martin Prikryl
- AppPublisherURL={#WebRoot}
- AppSupportURL={#WebForum}
- AppUpdatesURL={#WebRoot}eng/download.php
- VersionInfoCompany=Martin Prikryl
- VersionInfoDescription=Setup for WinSCP {#Version} (SFTP, FTP, WebDAV and SCP client)
- VersionInfoVersion={#Major}.{#Minor}.{#Rev}.{#Build}
- VersionInfoTextVersion={#Version}
- VersionInfoCopyright=(c) 2000-{#Year} Martin Prikryl
- VersionInfoOriginalFileName={#BaseFilename}.exe
- DefaultDirName={autopf}\WinSCP
- LicenseFile=license.setup.txt
- UninstallDisplayIcon={app}\WinSCP.exe
- OutputDir={#OutputDir}
- DisableStartupPrompt=yes
- AppVersion={#Version}
- AppVerName=WinSCP {#Version}
- OutputBaseFilename={#BaseFilename}
- SolidCompression=yes
- #ifdef ImagesDir
- WizardImageFile={#ImagesDir}\Tall *.bmp
- WizardSmallImageFile={#ImagesDir}\Square *.bmp
- #endif
- ShowTasksTreeLines=yes
- PrivilegesRequired=admin
- PrivilegesRequiredOverridesAllowed=commandline dialog
- ShowLanguageDialog=auto
- UsePreviousLanguage=yes
- DisableProgramGroupPage=yes
- MinVersion=6.0
- SetupIconFile=winscpsetup.ico
- DisableDirPage=no
- WizardStyle=modern
- ; We do not want the Explorer restarts as that is not pleasant to the user
- CloseApplications=no
- UsedUserAreasWarning=no
- #ifdef Sign
- SignTool=sign $f "WinSCP Installer" https://winscp.net/eng/docs/installation
- #endif
- [Languages]
- ; English has to be first so that it is pre-selected
- ; on Setup Select Language window, when no translation matching
- ; Windows UI locale is available
- Name: {#DefaultLang}; MessagesFile: {#MessagesPath(DefaultLang)}
- #define FindHandle
- #dim Languages[200]
- #define LanguageCount 0
- #define AnyLanguageComplete 0
- #define LangI
- ; For some reason the variable cannot be defined near the code where we use it
- #define AllTranslationsBuf
- #sub ProcessTranslationFile
- #define FileName FindGetFileName(FindHandle)
- #define Lang Copy(FileName, Pos(".", FileName)+1)
- #define LangNameFull ReadIni(MessagesPath(Lang), "LangOptions", "LanguageName")
- #define Sep Pos(" -", LangNameFull)
- #if Sep > 0
- #define LangName Copy(LangNameFull, 1, Sep - 1)
- #else
- #define LangName LangNameFull
- #endif
- #define LangID ReadIni(MessagesPath(Lang), "LangOptions", "LanguageID")
- #define LangCompleteness Int(ReadIni(MessagesPath(Lang), "CustomOptions", "TranslationCompleteness"))
- #expr Languages[LanguageCount*4] = Lang
- ; Not used atm
- #expr Languages[LanguageCount*4+1] = LangName
- ; Not used atm
- #expr Languages[LanguageCount*4+2] = LangID
- #expr Languages[LanguageCount*4+3] = LangCompleteness
- #expr LanguageCount++
- #if LangCompleteness >= CompletenessThreshold
- Name: {#Lang}; MessagesFile: {#MessagesPath(Lang)}
- #expr AnyLanguageComplete = 1
- #endif
- #endsub /* sub ProcessTranslationFile */
- #if FindHandle = FindFirst(TranslationDir + "\" + TranslationFileMask, 0)
- #define FResult 1
- #for {0; FResult; FResult = FindNext(FindHandle)} ProcessTranslationFile
- #expr FindClose(FindHandle)
- #endif
- ; Types are not used anymore, they are preserved only to let setup
- ; detect previous installation type and decide between typical/custom setup
- [Types]
- Name: full; Description: "full"
- Name: compact; Description: "compact"
- Name: custom; Description: "custom"; Flags: iscustom
- [Components]
- Name: main; Description: {cm:ApplicationComponent}; \
- Types: full custom compact; Flags: fixed
- Name: shellext; Description: {cm:ShellExtComponent}; \
- Types: full compact
- Name: pageant; Description: {cm:PageantComponent}; \
- Types: full
- Name: puttygen; Description: {cm:PuTTYgenComponent}; \
- Types: full
- #if AnyLanguageComplete == 1
- Name: transl; Description: {cm:TranslationsComponent}; \
- Types: full
- #endif
- [Tasks]
- Name: enableupdates; Description: {cm:EnableUpdates}
- Name: enableupdates\enablecollectusage; Description: {cm:EnableCollectUsage}
- ; Windows integration
- Name: desktopicon; Description: {cm:DesktopIconTask}
- Name: sendtohook; Description: {cm:SendToHookTask}
- Name: urlhandler; Description: {cm:RegisterAsUrlHandlers}
- Name: searchpath; Description: {cm:AddSearchPath}; \
- Flags: unchecked; Check: IsAdminInstallMode
- [Icons]
- Name: "{autoprograms}\WinSCP"; Filename: "{app}\WinSCP.exe"; Components: main; \
- Comment: "{cm:ProgramComment2}"
- ; This is created when desktopicon task is selected
- Name: "{autodesktop}\WinSCP"; Filename: "{app}\WinSCP.exe"; \
- Tasks: desktopicon; Comment: "{cm:ProgramComment2}"
- ; This is created when sendtohook task is selected
- Name: "{usersendto}\{cm:SendToHookNew}"; Filename: "{app}\WinSCP.exe"; \
- Parameters: "/upload"; Tasks: sendtohook
- [InstallDelete]
- ; Remove pre-5.8.2 PuTTY help file
- Type: files; Name: "{app}\PuTTY\putty.hlp"
- ; Remove pre-524 licence file (without .txt extension)
- Type: files; Name: "{app}\license"
- ; Remove pre-520 start menu folders
- Type: filesandordirs; Name: "{commonprograms}\WinSCP"
- Type: filesandordirs; Name: "{userprograms}\WinSCP"; Check: HasUserPrograms
- [Run]
- Filename: "{app}\WinSCP.exe"; Parameters: "/RegisterForDefaultProtocols"; \
- StatusMsg: {cm:RegisteringAsUrlHandlers}; Tasks: urlhandler
- Filename: "{app}\WinSCP.exe"; Parameters: "/AddSearchPath"; \
- StatusMsg: {cm:AddingSearchPath}; Tasks: searchpath
- Filename: "{app}\WinSCP.exe"; Parameters: "/ImportSitesIfAny"; \
- StatusMsg: {cm:ImportSites}; Flags: skipifsilent
- [UninstallDelete]
- ; These additional files are created by application
- Type: files; Name: "{app}\WinSCP.ini"
- Type: files; Name: "{app}\WinSCP.cgl"
- [Files]
- #ifdef ImagesDir
- ; Put these to the top as we extract them on demand and
- ; that can take long with solid compression enabled
- Source: "{#ImagesDir}\{#ExplorerFileBase} *.bmp"; Flags: dontcopy
- Source: "{#ImagesDir}\{#CommanderFileBase} *.bmp"; Flags: dontcopy
- Source: "{#ImagesDir}\{#SelectDirFileBase} *.bmp"; Flags: dontcopy
- #ifdef Donations
- Source: "{#ImagesDir}\{#PayPalCardImage}"; Flags: dontcopy
- #endif
- #endif
- Source: "{#MainFileSource}"; DestDir: "{app}"; \
- Components: main; Flags: ignoreversion
- Source: "{#ConsoleFileSource}"; DestDir: "{app}"; \
- Components: main; Flags: ignoreversion
- Source: "{#MapFileSource}"; DestDir: "{app}"; \
- Components: main; Flags: ignoreversion
- Source: "{#AssemblyFileSource}"; DestDir: "{app}"; \
- Components: main; Flags: ignoreversion
- Source: "license.txt"; DestDir: "{app}"; \
- Components: main; Flags: ignoreversion
- Source: "{#ShellExtFileSource}"; DestDir: "{app}"; \
- Components: shellext; \
- Flags: regserver restartreplace uninsrestartdelete ignoreversion; \
- Check: not IsWin64 and ShouldInstallShellExt(ExpandConstant('{app}\{#ShellExtFileName}'), '{#GetFileVersion(ShellExtFileSource)}')
- Source: "{#ShellExt64FileSource}"; DestDir: "{app}"; \
- Components: shellext; \
- Flags: regserver restartreplace uninsrestartdelete ignoreversion; \
- Check: IsWin64 and ShouldInstallShellExt(ExpandConstant('{app}\{#ShellExt64FileName}'), '{#GetFileVersion(ShellExt64FileSource)}')
- Source: "{#PuttySourceDir}\LICENCE"; DestDir: "{app}\PuTTY"; \
- Components: pageant puttygen; Flags: ignoreversion
- Source: "{#PuttySourceDir}\putty.chm"; DestDir: "{app}\PuTTY"; \
- Components: pageant puttygen; Flags: ignoreversion
- Source: "{#PuttySourceDir}\pageant.exe"; DestDir: "{app}\PuTTY"; \
- Components: pageant; Flags: ignoreversion
- Source: "{#PuttySourceDir}\puttygen.exe"; DestDir: "{app}\PuTTY"; \
- Components: puttygen; Flags: ignoreversion
- #ifdef ExtensionsDir
- Source: "{#ExtensionsDir}\*.*"; DestDir: "{app}\Extensions"
- #endif
- #ifdef Sponsor
- Source: "{#Sponsor}\*.*"; Flags: dontcopy skipifsourcedoesntexist
- #define SponsorImages
- #if FindHandle = FindFirst(Sponsor + "\*.*", 0)
- #define FResult 1
- #for {0; FResult; FResult = FindNext(FindHandle)} SponsorImages = SponsorImages + FindGetFileName(FindHandle) + ","
- #expr FindClose(FindHandle)
- #expr SponsorImages = Copy(SponsorImages, 1, Len(SponsorImages) - 1)
- #endif
- #endif
- [Registry]
- Root: HKCU; Subkey: "{#ParentRegistryKey}"; Flags: uninsdeletekeyifempty
- Root: HKCU; Subkey: "{#RegistryKey}"; Flags: uninsdeletekeyifempty
- ; Norton Commander interface
- Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
- ValueName: "Interface"; ValueData: 0; Check: UserSettings(1)
- Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
- ValueName: "DefaultInterfaceInterface"; ValueData: 0; \
- Check: UserSettings(1) and IsAdminInstallMode; Flags: noerror
- ; Explorer-like interface
- Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
- ValueName: "Interface"; ValueData: 1; Check: not UserSettings(1)
- Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
- ValueName: "DefaultInterfaceInterface"; ValueData: 1; \
- Check: (not UserSettings(1)) and IsAdminInstallMode; Flags: noerror
- ; If installer enabled ddext, let it reset the settings on uninstall,
- ; so the default is used on the next run
- Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
- ValueName: "DDExtEnabled"; ValueData: 1; Components: shellext; \
- Flags: uninsdeletevalue
- ; Updates
- Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface\Updates"; \
- ValueType: dword; ValueName: "Period"; ValueData: 7; \
- Tasks: enableupdates; Check: not UpdatesEnabled
- Root: HKLM; SubKey: "{#RegistryKey}"; \
- ValueType: dword; ValueName: "DefaultUpdatesPeriod"; ValueData: 7; \
- Tasks: enableupdates; Flags: noerror; Check: IsAdminInstallMode
- Root: HKLM; SubKey: "{#RegistryKey}"; \
- ValueType: dword; ValueName: "DefaultCollectUsage"; ValueData: 1; \
- Tasks: enableupdates\enablecollectusage; Flags: noerror; Check: IsAdminInstallMode
- #sub EmitLang
- #if Languages[LangI*4+3] >= InclusionThreshold
- [Files]
- Source: "{#TranslationDir}\WinSCP.{#Languages[LangI*4]}"; DestDir: "{app}\Translations"; \
- Components: transl; Flags: ignoreversion
- #endif
- #endsub /* sub EmitLang */
- #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang
- ; Delete translations from installation root folder (pre-5.10)
- [InstallDelete]
- #expr AllTranslationsBuf = AllTranslations + '-'
- #sub DeleteRootTranslation
- #define P Pos('-', AllTranslationsBuf)
- #define Lang Copy(AllTranslationsBuf, 1, P - 1)
- #expr AllTranslationsBuf = Copy(AllTranslationsBuf, P + 1)
- Type: files; Name: "{app}\WinSCP.{#Lang}"
- #endsub
- #for { 0; Len(AllTranslationsBuf) > 0; 0 } DeleteRootTranslation
- [UninstallRun]
- ; Make sure no later uninstall task recreate the configuration
- Filename: "{app}\WinSCP.exe"; Parameters: "/UninstallCleanup"; \
- RunOnceId: "UninstallCleanup"
- Filename: "{app}\WinSCP.exe"; Parameters: "/RemoveSearchPath"; \
- RunOnceId: "RemoveSearchPath"
- Filename: "{app}\WinSCP.exe"; Parameters: "/UnregisterForProtocols"; \
- RunOnceId: "UnregisterForProtocols"
- [Code]
- const
- NewLine = #13#10;
- var
- TypicalTypeButton: TRadioButton;
- CustomTypeButton: TRadioButton;
- CommanderRadioButton: TRadioButton;
- ExplorerRadioButton: TRadioButton;
- LaunchCheckbox: TCheckbox;
- OpenGettingStartedCheckbox: TCheckbox;
- AreUpdatesEnabled: Boolean;
- AutomaticUpdate: Boolean;
- Upgrade: Boolean;
- PrevVersion: string;
- ShellExtNewerCacheFileName: string;
- ShellExtNewerCacheResult: Boolean;
- ShellExtNoRestart: Boolean;
- #ifdef Donations
- DonationPanel: TPanel;
- AboutDonationCaption: TLabel;
- #endif
- InstallationDone: Boolean;
- LicenseAccepted: Boolean;
- InitDir: string;
- InitComponents: string;
- InitTasks: string;
- InitInterface: Integer;
- Donated: Boolean;
- InterfacePage: TWizardPage;
- SetupTypePage: TWizardPage;
- #ifdef Sponsor
- SponsorReq: Variant;
- SponsorPage: TWizardPage;
- Sponsor: string;
- SponsorStatus: string;
- #endif
- procedure ShowMessage(Text: string);
- begin
- MsgBox(Text, mbInformation, MB_OK);
- end;
- #ifdef Sponsor
- function IsWinVista: Boolean;
- begin
- Result := (GetWindowsVersion >= $06000000);
- end;
- #endif
- procedure CutVersionPart(var VersionString: string; var VersionPart: Word);
- var
- P: Integer;
- begin
- P := Pos('.', VersionString);
- if P > 0 then
- begin
- VersionPart := StrToIntDef(Copy(VersionString, 1, P - 1), 0);
- Delete(VersionString, 1, P);
- end
- else
- begin
- VersionPart := StrToIntDef(VersionString, 0);
- VersionString := '';
- end;
- end;
- function ShouldInstallShellExt(FileName: string; InstalledVersion: string): Boolean;
- var
- ExistingMS, ExistingLS: Cardinal;
- ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild: Cardinal;
- InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild: Word;
- begin
- if ShellExtNewerCacheFileName = FileName then
- begin
- if ShellExtNewerCacheResult then
- begin
- Log(Format('Allowing installation of shell extension %s as already decided', [FileName]));
- Result := True;
- end
- else
- begin
- Log(Format('Skipping installation of shell extension %s as already decided', [FileName]));
- Result := False;
- end;
- // Keeping ShellExtNoRestart value
- end
- else
- if not FileExists(FileName) then
- begin
- Log(Format('Shell extension %s does not exist yet, allowing installation', [FileName]));
- ShellExtNoRestart := False;
- Result := True;
- end
- else
- if not GetVersionNumbers(FileName, ExistingMS, ExistingLS) then
- begin
- Log(Format('Cannot retrieve version of existing shell extension %s, allowing installation', [FileName]));
- ShellExtNoRestart := False;
- Result := True;
- end
- else
- begin
- ExistingMajor := ExistingMS shr 16;
- ExistingMinor := ExistingMS and $FFFF;
- ExistingRev := ExistingLS shr 16;
- ExistingBuild := ExistingLS and $FFFF;
- Log(Format('Existing shell extension %s version: %d.%d.%d[.%d]', [FileName, ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild]));
- Log(Format('Installed extension version string: %s', [InstalledVersion]));
- CutVersionPart(InstalledVersion, InstalledMajor);
- CutVersionPart(InstalledVersion, InstalledMinor);
- CutVersionPart(InstalledVersion, InstalledRev);
- CutVersionPart(InstalledVersion, InstalledBuild);
- Log(Format('Installed extension version: %d.%d.%d[.%d]', [InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild]));
- if (InstalledMajor <> ExistingMajor) or
- ((ExistingMajor = 1) and (ExistingMinor <= 1)) then
- begin
- // Still on 1.x, so this won't be used when upgrading,
- // but it will be useful, if downgrading from future version with a different major version.
- if InstalledMajor <> ExistingMajor then
- begin
- Log('Existing extension has different major version, allowing installation, and will require restart, if it is locked.')
- end
- else
- begin
- // 1.1 uses Ansi encoding, and is incompatible with 1.2 and newer which uses Unicode
- Log('Existing extension is 1.1 or older, allowing installation, and will require restart, if it is locked.');
- end;
- Result := True;
- ShellExtNoRestart := False;
- end
- else
- if (InstalledMinor > ExistingMinor) or
- ((InstalledMinor = ExistingMinor) and (InstalledRev > ExistingRev)) then
- begin
- Log('Installed extension is newer than existing extension, but major version is the same, allowing installation, but we will delay replacing the extension until the next system start, if it is locked.');
- Result := True;
- ShellExtNoRestart := True;
- end
- else
- begin
- Log('Installed extension is same or older than existing extension (but the same major version), skipping installation');
- ShellExtNoRestart := False;
- Result := False;
- end;
- end;
- ShellExtNewerCacheFileName := FileName;
- ShellExtNewerCacheResult := Result;
- end;
- function UpdatesEnabled: Boolean;
- begin
- Result := AreUpdatesEnabled;
- end;
- function UserSettings(Settings: Integer): Boolean;
- begin
- case Settings of
- 1: Result := CommanderRadioButton.Checked;
- else Result := False;
- end;
- end;
- function LanguageCompleteness(Lang: string): Integer;
- begin
- #sub EmitLang4
- if (Lang = '{#Languages[LangI*4]}') then
- begin
- Result := {#Languages[LangI*4+3]};
- end
- else
- #endsub /* sub EmitLang4 */
- #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang4
- // used also for the default language
- Result := 100;
- end;
- procedure OpenBrowser(Url: string);
- var
- ErrorCode: Integer;
- begin
- ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
- end;
- function IsRestartPage: Boolean;
- begin
- Result := WizardForm.YesRadio.Visible;
- end;
- #ifdef Sponsor
- var
- SponsoringClicked: Boolean;
- procedure SponsoringLinkLabelClick(Sender: TObject);
- begin
- SponsoringClicked := True;
- OpenBrowser('{#WebReport}?mode=sponsoring' + Format('&sponsor=%s&', [Sponsor]) + ExpandConstant('{#WebArguments}'));
- end;
- #endif
- procedure OpenHelp;
- var
- HelpKeyword: string;
- begin
- HelpKeyword := 'ui_installer'; // default
- case WizardForm.CurPageID of
- wpLicense:
- HelpKeyword := 'ui_installer_license';
- wpSelectDir:
- HelpKeyword := 'ui_installer_selectdir';
- wpSelectComponents:
- HelpKeyword := 'ui_installer_selectcomponents';
- wpSelectTasks:
- HelpKeyword := 'ui_installer_selecttasks';
- wpReady:
- HelpKeyword := 'ui_installer_ready';
- wpFinished:
- HelpKeyword := 'ui_installer_finished';
- SetupTypePage.ID:
- HelpKeyword := 'ui_installer_setuptype';
- InterfacePage.ID:
- HelpKeyword := 'ui_installer_interface';
- #ifdef Sponsor
- SponsorPage.ID:
- begin
- SponsoringLinkLabelClick(nil);
- Exit;
- end;
- #endif
- end;
- OpenBrowser('{#WebDocumentation}' + HelpKeyword + '?' + ExpandConstant('{#WebArguments}'));
- end;
- procedure HelpButtonClick(Sender: TObject);
- begin
- OpenHelp;
- end;
- procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
- begin
- if Key = 112 { VK_F1 } then
- begin
- OpenHelp;
- Key := 0;
- end;
- end;
- procedure CaptionClick(Sender: TObject);
- begin
- WizardForm.ActiveControl := TLabel(Sender).FocusControl;
- end;
- procedure ImageClick(Sender: TObject);
- begin
- WizardForm.ActiveControl := TWinControl(TControl(Sender).Tag);
- end;
- function WillRestart: Boolean;
- begin
- Result := WizardForm.YesRadio.Visible and WizardForm.YesRadio.Checked;
- end;
- procedure UpdatePostInstallRunCheckboxes(Sender: TObject);
- begin
- LaunchCheckbox.Enabled := not WillRestart;
- OpenGettingStartedCheckbox.Enabled :=
- LaunchCheckbox.Enabled
- end;
- procedure LinkLabel(Control: TLabel);
- begin
- Control.ParentFont := True;
- Control.Font.Style := Control.Font.Style + [fsUnderline];
- Control.Font.Color := clBlue;
- Control.Cursor := crHand;
- end;
- function IsTypicalInstallation: Boolean;
- begin
- Result := TypicalTypeButton.Checked;
- end;
- #ifdef Donations
- procedure AboutDonationsLinkClick(Sender: TObject);
- begin
- OpenBrowser('{#WebRoot}eng/donate.php?' + ExpandConstant('{#WebArguments}'));
- Donated := true;
- end;
- procedure DonateLinkClick(Sender: TObject);
- var
- Control: TControl;
- begin
- Control := TControl(Sender);
- OpenBrowser('{#WebRoot}eng/donate.php?amount=' + IntToStr(Control.Tag) + '¤cy=' + CustomMessage('Currency') + '&' + ExpandConstant('{#WebArguments}'));
- Donated := true;
- end;
- procedure CreateDonateLink(Amount: Integer; var Top: Integer);
- var
- Caption: TLabel;
- begin
- Caption := TLabel.Create(DonationPanel);
- Caption.Left := 0;
- Caption.Top := Top;
- Caption.Tag := Amount;
- Caption.Parent := DonationPanel;
- Caption.Caption := Format(CustomMessage('Donate'), ['$' + IntToStr(Amount)]);
- Caption.OnClick := @DonateLinkClick;
- LinkLabel(Caption);
- Top := Top + ScaleY(16);
- end;
- #endif
- const
- fsSurface = 0;
- procedure LoadBitmap(Image: TBitmapImage; FileName: string; BackgroundColor: TColor);
- var
- Bitmap: TBitmap;
- begin
- Bitmap := TBitmap.Create();
- Bitmap.AlphaFormat := afDefined;
- Bitmap.LoadFromFile(FileName);
- Image.Bitmap := Bitmap;
- Bitmap.Free;
- Image.BackColor := BackgroundColor;
- end;
- procedure LoadEmbededBitmap(Image: TBitmapImage; Name: string; BackgroundColor: TColor);
- var
- FileName: string;
- begin
- ExtractTemporaryFile(Name);
- FileName := ExpandConstant('{tmp}\' + Name);
- LoadBitmap(Image, FileName, BackgroundColor);
- // we won't need this anymore
- DeleteFile(FileName);
- end;
- function GetScalingFactor: Integer;
- begin
- if WizardForm.Font.PixelsPerInch >= 192 then Result := 200
- else
- if WizardForm.Font.PixelsPerInch >= 144 then Result := 150
- else
- if WizardForm.Font.PixelsPerInch >= 120 then Result := 125
- else Result := 100;
- end;
- procedure LoadEmbededScaledIcon(Image: TBitmapImage; NameBase: string; SizeBase: Integer; BackgroundColor: TColor);
- var
- Name: String;
- begin
- Name := Format('%s %d.bmp', [NameBase, SizeBase * GetScalingFactor div 100]);
- LoadEmbededBitmap(Image, Name, BackgroundColor);
- Image.AutoSize := True;
- end;
- // WORKAROUND
- // Checkboxes and Radio buttons created on runtime do
- // not scale their height automatically
- procedure ScaleFixedHeightControl(Control: TButtonControl);
- begin
- Control.Height := ScaleY(Control.Height);
- end;
- function GetBottom(Control: TControl): Integer;
- begin
- Result := Control.Top + Control.Height;
- end;
- function GetRight(Control: TControl): Integer;
- begin
- Result := Control.Left + Control.Width;
- end;
- function CmdLineParamExists(const Value: string): Boolean;
- var
- I: Integer;
- begin
- Result := False;
- for I := 1 to ParamCount do
- begin
- if CompareText(ParamStr(I), Value) = 0 then
- begin
- Result := True;
- Exit;
- end;
- end;
- end;
- function InitializeSetup: Boolean;
- var
- WaitInterval: Integer;
- Wait: Integer;
- begin
- AutomaticUpdate := CmdLineParamExists('/AutomaticUpdate');
- if AutomaticUpdate then
- begin
- Log('Automatic update');
- Wait := 10000;
- end
- else
- begin
- Wait := 0;
- end;
- WaitInterval := 250;
- while (Wait > 0) and CheckForMutexes('{#AppMutex}') do
- begin
- Log('Application is still running, waiting');
- Sleep(WaitInterval);
- Wait := Wait - WaitInterval;
- end;
- while CheckForMutexes('{#AppMutex}') do
- begin
- if MsgBox(
- FmtMessage(SetupMessage(msgSetupAppRunningError), ['WinSCP']),
- mbError, MB_OKCANCEL) <> IDOK then
- begin
- Abort;
- end;
- end;
- Result := True;
- end;
- function Bullet(S: string): string;
- begin
- if Copy(S, 1, 1) = '-' then S := #$2022' ' + Trim(Copy(S, 2, Length(S) - 1));
- Result := S;
- end;
- procedure InitializeWizard;
- var
- UserInterface: Cardinal;
- UpdatesPeriod: Cardinal;
- Caption: TLabel;
- #ifdef ImagesDir
- Image: TBitmapImage;
- #endif
- HelpButton: TButton;
- #ifdef Donations
- P: Integer;
- #ifdef ImagesDir
- P2: Integer;
- #endif
- #endif
- S: string;
- Completeness: Integer;
- begin
- InstallationDone := False;
- LicenseAccepted := False;
- InitInterface := -1;
- Upgrade :=
- // We may want to use HKA to work correctly with side-by-side installations.
- // But as Updade is really used for changing REGISTRY configuration options only,
- // which are shared between all-users and current-user installations, it does not really matter.
- RegQueryStringValue(HKLM, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S) or
- RegQueryStringValue(HKCU, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S);
- if Upgrade then
- begin
- Log('Upgrade');
- end
- else
- begin
- Log('New installation');
- end;
- if Upgrade and GetVersionNumbersString(AddBackslash(WizardDirValue) + '{#MainFileName}', PrevVersion) and
- (PrevVersion[2] = '.') and (PrevVersion[4] = '.') and (PrevVersion[6] = '.') then
- begin
- PrevVersion := Copy(PrevVersion, 1, 5);
- end;
- WizardForm.KeyPreview := True;
- WizardForm.OnKeyDown := @FormKeyDown;
- // allow installation without requiring user to accept license
- WizardForm.LicenseAcceptedRadio.Checked := True;
- WizardForm.LicenseAcceptedRadio.Visible := False;
- WizardForm.LicenseNotAcceptedRadio.Visible := False;
- WizardForm.LicenseMemo.Height :=
- GetBottom(WizardForm.LicenseNotAcceptedRadio) -
- WizardForm.LicenseMemo.Top - ScaleY(5);
- // hide installation types combo
- WizardForm.TypesCombo.Visible := False;
- WizardForm.ComponentsList.Height :=
- GetBottom(WizardForm.ComponentsList) -
- WizardForm.TypesCombo.Top;
- WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
- // add help button
- HelpButton := TButton.Create(WizardForm);
- HelpButton.Parent := WizardForm;
- HelpButton.Anchors := [akLeft, akBottom];
- HelpButton.Left := WizardForm.ClientWidth - GetRight(WizardForm.CancelButton);
- HelpButton.Top := WizardForm.CancelButton.Top;
- HelpButton.Width := WizardForm.CancelButton.Width;
- HelpButton.Height := WizardForm.CancelButton.Height;
- HelpButton.Caption := CustomMessage('HelpButton');
- HelpButton.OnClick := @HelpButtonClick;
- Completeness := LanguageCompleteness(ActiveLanguage);
- if (Completeness < 100) and (not WizardSilent) then
- begin
- ShowMessage(FmtMessage(CustomMessage('IncompleteTranslation'), [IntToStr(Completeness)]));
- end;
- // installation type page
- SetupTypePage := CreateCustomPage(wpLicense,
- CustomMessage('SetupTypeTitle'),
- CustomMessage('SetupTypePrompt'));
- TypicalTypeButton := TRadioButton.Create(SetupTypePage);
- if not Upgrade then
- S := CustomMessage('TypicalType')
- else
- S := CustomMessage('TypicalUpgradeType');
- TypicalTypeButton.Caption :=
- FmtMessage(CustomMessage('Recommended'), [S]);
- // check typical install, if typical install was installed before or
- // when version without setup type support was installed with
- // "full" installation or when there were no installation before
- // ("full" installation is default)
- TypicalTypeButton.Checked :=
- ((GetPreviousData('{#SetupTypeData}', '') = 'typical')) or
- ((GetPreviousData('{#SetupTypeData}', '') = '') and
- (WizardSetupType(False) = 'full'));
- TypicalTypeButton.Left := ScaleX(4);
- TypicalTypeButton.Width := SetupTypePage.SurfaceWidth -
- TypicalTypeButton.Left;
- ScaleFixedHeightControl(TypicalTypeButton);
- TypicalTypeButton.Parent := SetupTypePage.Surface;
- Caption := TLabel.Create(SetupTypePage);
- Caption.WordWrap := True;
- if not Upgrade then
- begin
- Caption.Caption :=
- Bullet(CustomMessage('TypicalType1')) + NewLine +
- Bullet(CustomMessage('TypicalType2')) + NewLine +
- Bullet(CustomMessage('TypicalType3'));
- end
- else
- begin
- Caption.Caption :=
- Bullet(CustomMessage('TypicalUpgradeType1'));
- end;
- Caption.Left := ScaleX(4) + ScaleX(20);
- Caption.Width := SetupTypePage.SurfaceWidth - Caption.Left;
- Caption.Top := GetBottom(TypicalTypeButton) + ScaleY(6);
- Caption.Parent := SetupTypePage.Surface;
- Caption.FocusControl := TypicalTypeButton;
- Caption.OnClick := @CaptionClick;
- CustomTypeButton := TRadioButton.Create(SetupTypePage);
- if not Upgrade then
- CustomTypeButton.Caption := CustomMessage('CustomType')
- else
- CustomTypeButton.Caption := CustomMessage('CustomUpgradeType');
- CustomTypeButton.Checked := (not TypicalTypeButton.Checked);
- CustomTypeButton.Left := ScaleX(4);
- CustomTypeButton.Width := SetupTypePage.SurfaceWidth -
- CustomTypeButton.Left;
- CustomTypeButton.Top := GetBottom(Caption) + ScaleY(10);
- ScaleFixedHeightControl(CustomTypeButton);
- CustomTypeButton.Parent := SetupTypePage.Surface;
- Caption := TLabel.Create(SetupTypePage);
- Caption.WordWrap := True;
- if not Upgrade then
- begin
- Caption.Caption :=
- Bullet(CustomMessage('CustomType1'));
- end
- else
- begin
- Caption.Caption :=
- Bullet(CustomMessage('CustomUpgradeType1')) + NewLine +
- Bullet(CustomMessage('CustomUpgradeType2'));
- end;
- Caption.Left := ScaleX(4) + ScaleX(20);
- Caption.Width := SetupTypePage.SurfaceWidth - Caption.Left;
- Caption.Top := GetBottom(CustomTypeButton) + ScaleY(6);
- Caption.Parent := SetupTypePage.Surface;
- Caption.FocusControl := CustomTypeButton;
- Caption.OnClick := @CaptionClick;
- // interface page
- InterfacePage := CreateCustomPage(wpSelectTasks,
- CustomMessage('UserSettingsTitle'),
- CustomMessage('UserSettingsPrompt'));
- UpdatesPeriod := 0;
- RegQueryDWordValue(HKCU, '{#RegistryKey}\Configuration\Interface\Updates',
- 'Period', UpdatesPeriod);
- AreUpdatesEnabled := (UpdatesPeriod <> 0);
- UserInterface := 0; { default is commander }
- RegQueryDWordValue(HKCU, '{#RegistryKey}\Configuration\Interface',
- 'Interface', UserInterface);
- Caption := TLabel.Create(InterfacePage);
- Caption.Caption := CustomMessage('UserInterfaceStyle');
- Caption.Width := InterfacePage.SurfaceWidth;
- Caption.Parent := InterfacePage.Surface;
- CommanderRadioButton := TRadioButton.Create(InterfacePage);
- CommanderRadioButton.Caption := CustomMessage('NortonCommanderInterfaceC');
- CommanderRadioButton.Checked := (UserInterface = 0);
- CommanderRadioButton.Left := ScaleX(4);
- CommanderRadioButton.Width := ScaleX(116);
- CommanderRadioButton.Top := GetBottom(Caption) + ScaleY(6);
- ScaleFixedHeightControl(CommanderRadioButton);
- CommanderRadioButton.Parent := InterfacePage.Surface;
- #ifdef ImagesDir
- Image := TBitmapImage.Create(InterfacePage);
- Image.Top := GetBottom(CommanderRadioButton) + ScaleY(6);
- Image.Left := CommanderRadioButton.Left + ScaleX(45);
- Image.Parent := InterfacePage.Surface;
- LoadEmbededScaledIcon(Image, '{#CommanderFileBase}', 32, InterfacePage.Surface.Color);
- Image.OnClick := @ImageClick;
- Image.Tag := Integer(CommanderRadioButton);
- #endif
- Caption := TLabel.Create(InterfacePage);
- Caption.WordWrap := True;
- Caption.Caption :=
- Bullet(CustomMessage('NortonCommanderInterface1')) + NewLine +
- Bullet(CustomMessage('NortonCommanderInterface2')) + NewLine +
- Bullet(CustomMessage('NortonCommanderInterface3'));
- Caption.Anchors := [akLeft, akTop, akRight];
- Caption.Left := GetRight(CommanderRadioButton);
- Caption.Width := InterfacePage.SurfaceWidth - Caption.Left;
- Caption.Top := CommanderRadioButton.Top;
- Caption.Parent := InterfacePage.Surface;
- Caption.FocusControl := CommanderRadioButton;
- Caption.OnClick := @CaptionClick;
- ExplorerRadioButton := TRadioButton.Create(InterfacePage);
- ExplorerRadioButton.Caption := CustomMessage('ExplorerInterfaceC');
- ExplorerRadioButton.Checked := (UserInterface <> 0);
- ExplorerRadioButton.Left := ScaleX(4);
- ExplorerRadioButton.Width := CommanderRadioButton.Width;
- ExplorerRadioButton.Top := GetBottom(Caption) + ScaleY(10);
- ScaleFixedHeightControl(ExplorerRadioButton);
- ExplorerRadioButton.Parent := InterfacePage.Surface;
- #ifdef ImagesDir
- Image := TBitmapImage.Create(InterfacePage);
- Image.Top := GetBottom(ExplorerRadioButton) + ScaleY(6);
- Image.Left := ExplorerRadioButton.Left + ScaleX(45);
- Image.Parent := InterfacePage.Surface;
- LoadEmbededScaledIcon(Image, '{#ExplorerFileBase}', 32, InterfacePage.Surface.Color);
- Image.OnClick := @ImageClick;
- Image.Tag := Integer(ExplorerRadioButton);
- #endif
- Caption := TLabel.Create(InterfacePage);
- Caption.WordWrap := True;
- Caption.Caption :=
- Bullet(CustomMessage('ExplorerInterface1')) + NewLine +
- Bullet(CustomMessage('ExplorerInterface2')) + NewLine +
- Bullet(CustomMessage('ExplorerInterface3'));
- Caption.Anchors := [akLeft, akTop, akRight];
- Caption.Left := GetRight(ExplorerRadioButton);
- Caption.Width := InterfacePage.SurfaceWidth - Caption.Left;
- Caption.Top := ExplorerRadioButton.Top;
- Caption.Parent := InterfacePage.Surface;
- Caption.FocusControl := ExplorerRadioButton;
- Caption.OnClick := @CaptionClick;
- // run checkbox
- LaunchCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
- LaunchCheckbox.Caption := CustomMessage('Launch');
- LaunchCheckbox.Checked := True;
- LaunchCheckbox.Left := WizardForm.YesRadio.Left;
- LaunchCheckbox.Width := WizardForm.YesRadio.Width;
- ScaleFixedHeightControl(LaunchCheckbox);
- LaunchCheckbox.Parent := WizardForm.FinishedPage;
- OpenGettingStartedCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
- OpenGettingStartedCheckbox.Caption := CustomMessage('OpenGettingStarted');
- OpenGettingStartedCheckbox.Checked := True;
- OpenGettingStartedCheckbox.Left := WizardForm.YesRadio.Left;
- OpenGettingStartedCheckbox.Width := WizardForm.YesRadio.Width;
- ScaleFixedHeightControl(OpenGettingStartedCheckbox);
- OpenGettingStartedCheckbox.Parent := WizardForm.FinishedPage;
- #ifdef Donations
- DonationPanel := TPanel.Create(WizardForm.FinishedPage);
- DonationPanel.Left := WizardForm.YesRadio.Left;
- DonationPanel.Width := WizardForm.YesRadio.Width;
- DonationPanel.Parent := WizardForm.FinishedPage;
- DonationPanel.BevelInner := bvNone;
- DonationPanel.BevelOuter := bvNone;
- DonationPanel.Color := WizardForm.FinishedPage.Color;
- Caption := TLabel.Create(DonationPanel);
- Caption.WordWrap := True;
- Caption.Caption := CustomMessage('PleaseDonate');
- Caption.Anchors := [akLeft, akTop, akRight];
- Caption.Left := 0;
- Caption.Top := 0;
- Caption.Width := DonationPanel.Width;
- Caption.Parent := DonationPanel;
- P := GetBottom(Caption) + ScaleY(12);
- #ifdef ImagesDir
- P2 := P;
- #endif
- CreateDonateLink( 9, P);
- CreateDonateLink(19, P);
- CreateDonateLink(49, P);
- AboutDonationCaption := TLabel.Create(DonationPanel);
- AboutDonationCaption.Left := 0;
- AboutDonationCaption.Top := P;
- AboutDonationCaption.Parent := DonationPanel;
- AboutDonationCaption.Caption := CustomMessage('AboutDonations');
- AboutDonationCaption.OnClick := @AboutDonationsLinkClick;
- LinkLabel(AboutDonationCaption);
- #ifdef ImagesDir
- Image := TBitmapImage.Create(DonationPanel);
- LoadEmbededBitmap(Image, '{#PayPalCardImage}', DonationPanel.Color);
- Image.AutoSize := True;
- Image.Cursor := crHand;
- Image.Parent := DonationPanel;
- Image.Left := ScaleX(108);
- Image.Top := P2 + ScaleX(8);
- Image.Hint := CustomMessage('AboutDonations');
- Image.ShowHint := True;
- Image.OnClick := @AboutDonationsLinkClick;
- #endif
- DonationPanel.Height := GetBottom(AboutDonationCaption);
- #endif
- WizardForm.YesRadio.OnClick := @UpdatePostInstallRunCheckboxes;
- WizardForm.NoRadio.OnClick := @UpdatePostInstallRunCheckboxes;
- UpdatePostInstallRunCheckboxes(nil);
- #ifdef ImagesDir
- // Text does not scale as quick as with DPI,
- // so the icon may overlap the labels. Shift them.
- P := WizardForm.SelectDirBitmapImage.Width;
- LoadEmbededScaledIcon(WizardForm.SelectDirBitmapImage, '{#SelectDirFileBase}', 32, WizardForm.SelectDirPage.Color);
- P := (WizardForm.SelectDirBitmapImage.Width - P);
- // Vertical change should be the same as horizontal
- WizardForm.SelectDirLabel.Left := WizardForm.SelectDirLabel.Left + P;
- WizardForm.SelectDirBrowseLabel.Top := WizardForm.SelectDirBrowseLabel.Top + P;
- WizardForm.DirEdit.Top := WizardForm.DirEdit.Top + P;
- WizardForm.DirBrowseButton.Top := WizardForm.DirBrowseButton.Top + P;
- #endif
- end;
- procedure RegisterPreviousData(PreviousDataKey: Integer);
- var
- S: string;
- begin
- if IsTypicalInstallation then S := 'typical'
- else S := 'custom';
- SetPreviousData(PreviousDataKey, '{#SetupTypeData}', S);
- end;
- function SaveCheckListBoxState(ListBox: TNewCheckListBox): string;
- var
- I: Integer;
- begin
- for I := 0 to ListBox.Items.Count - 1 do
- begin
- Result := Result + IntToStr(Integer(ListBox.State[I]));
- end;
- end;
- procedure CurPageChanged(CurPageID: Integer);
- var
- Delta: Integer;
- LineHeight: Integer;
- LaunchCheckboxTop: Integer;
- S: string;
- #ifdef Sponsor
- SponsorQueryUrl: string;
- PreferredSponsor: string;
- #endif
- begin
- if CurPageID = wpLicense then
- begin
- WizardForm.NextButton.Caption := CustomMessage('AcceptButton')
- end;
- if CurPageID = wpSelectDir then
- begin
- if InitDir = '' then
- InitDir := WizardForm.DirEdit.Text;
- end
- else
- if CurPageID = wpSelectComponents then
- begin
- if InitComponents = '' then
- InitComponents := SaveCheckListBoxState(WizardForm.ComponentsList);
- end
- else
- if CurPageID = wpSelectTasks then
- begin
- if InitTasks = '' then
- InitTasks := SaveCheckListBoxState(WizardForm.TasksList);
- end
- else
- if CurPageID = InterfacePage.ID then
- begin
- if InitInterface < 0 then
- InitInterface := Integer(CommanderRadioButton.Checked);
- end
- else
- if CurPageID = wpFinished then
- begin
- LineHeight := (WizardForm.NoRadio.Top - WizardForm.YesRadio.Top);
- // Are we at the "Restart?" screen
- // Note that it's not possible to get to the "finished" page more than once,
- // so the code below does not expect re-entry
- if IsRestartPage then
- begin
- if ShellExtNoRestart then
- begin
- Log('Hiding restart page as it''s not critical to replace the shell extension');
- WizardForm.YesRadio.Visible := False;
- WizardForm.NoRadio.Visible := False;
- WizardForm.NoRadio.Checked := True;
- S := SetupMessage(msgFinishedLabel);
- StringChange(S, '[name]', 'WinSCP');
- WizardForm.FinishedLabel.Caption :=
- S + NewLine + NewLine +
- // The additional new line is a padding for the "launch check box",
- // as the same padding is there for the YesRadio too.
- SetupMessage(msgClickFinish) + NewLine;
- Log(WizardForm.FinishedLabel.Caption);
- Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
- LaunchCheckboxTop := WizardForm.YesRadio.Top + Delta;
- end
- else
- begin
- WizardForm.FinishedLabel.Caption :=
- CustomMessage('FinishedRestartDragExtLabel') + NewLine;
- Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
- WizardForm.YesRadio.Top := WizardForm.YesRadio.Top + Delta;
- WizardForm.NoRadio.Top := WizardForm.NoRadio.Top + Delta;
- LaunchCheckboxTop := WizardForm.NoRadio.Top + LineHeight;
- #ifdef Donations
- DonationPanel.Visible := False;
- #endif
- end;
- end
- else
- begin
- LaunchCheckboxTop := WizardForm.RunList.Top;
- end;
- LaunchCheckbox.Top := LaunchCheckboxTop;
- OpenGettingStartedCheckbox.Top := LaunchCheckbox.Top + LineHeight;
- UpdatePostInstallRunCheckboxes(nil);
- #ifdef Donations
- if DonationPanel.Visible then
- begin
- DonationPanel.Top := GetBottom(OpenGettingStartedCheckbox) + ScaleY(12);
- // Hide "about donations" if it does not fit nicely
- // (happens on "long" languages, as German)
- // Should not happen anymore with "modern" style of IS6.
- if (DonationPanel.Top + GetBottom(AboutDonationCaption)) >
- (WizardForm.FinishedPage.Height - ScaleY(8)) then
- begin
- AboutDonationCaption.Visible := False;
- end;
- end;
- #endif
- end
- else
- if CurPageID = SetupTypePage.ID then
- begin
- Log('License accepted');
- LicenseAccepted := True;
- #ifdef Sponsor
- if VarIsEmpty(SponsorReq) then
- begin
- // Need Vista for SHCONTCH_* constants
- if WizardSilent or CmdLineParamExists('/NoSponsor') or (not IsWinVista) then
- begin
- Log('Skipping sponsor query request');
- SponsorStatus := 'N';
- end
- else
- begin
- SponsorPage :=
- CreateCustomPage(wpInstalling, 'Release sponsor', 'Please read a message from the sponsor of this release.');
- SponsorQueryUrl :=
- '{#WebReport}?' +
- Format('mode=sponsorrequest&ver=%s&lang=%s&prevver=%s&scale=%d&images=%s', [
- '{#VersionOnly}', ActiveLanguage, PrevVersion, GetScalingFactor, '{#SponsorImages}']);
- PreferredSponsor := ExpandConstant('{param:Sponsor}');
- if PreferredSponsor <> '' then
- begin
- SponsorQueryUrl := SponsorQueryUrl + Format('&sponsor=%s', [PreferredSponsor]);
- end;
- Log('Sending sponsor query request: ' + SponsorQueryUrl);
- SponsorReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
- SponsorReq.Open('GET', SponsorQueryUrl, True);
- SponsorReq.Send('');
- end;
- end;
- #endif
- end;
- end;
- function AskedRestart: Boolean;
- begin
- Result := IsRestartPage;
- end;
- procedure DeinitializeSetup;
- var
- WinHttpReq: Variant;
- ReportUrl: string;
- ReportData: string;
- begin
- // cannot send report, unless user already accepted license
- // (with privacy policy)
- if LicenseAccepted then
- begin
- Log('Preparing installation report');
- ReportData := Format(
- 'mode=report&installed=%d&silent=%d&ver=%s&lang=%s&prevver=%s&', [
- Integer(InstallationDone), Integer(WizardSilent),
- '{#VersionOnly}', ActiveLanguage,
- PrevVersion]);
- #ifdef Sponsor
- ReportData := ReportData +
- Format('sponsorstatus=%s&sponsor=%s&sponsoringclicked=%d&', [SponsorStatus, Sponsor, Integer(SponsoringClicked)]);
- #endif
- try
- ReportUrl := '{#WebReport}?' + ReportData;
- Log('Sending installation report: ' + ReportUrl);
- WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
- WinHttpReq.Open('GET', ReportUrl, False);
- WinHttpReq.Send('');
- Log('Installation report send result: ' + IntToStr(WinHttpReq.Status) + ' ' + WinHttpReq.StatusText);
- except
- Log('Error sending installation report: ' + GetExceptionMessage);
- end;
- end;
- end;
- procedure ExecApp(Params: string; ShowCmd: Integer; Wait: TExecWait);
- var
- Path: string;
- ErrorCode: Integer;
- begin
- Path := ExpandConstant('{app}\{#MainFileName}');
- ExecAsOriginalUser(Path, Params, '', ShowCmd, Wait, ErrorCode)
- end;
- procedure OpenBrowserGettingStarted;
- var
- WebGettingStarted: string;
- begin
- WebGettingStarted :=
- ExpandConstant('{#WebGettingStarted}') + PrevVersion +
- '&automatic=' + IntToStr(Integer(AutomaticUpdate));
- Log('Opening getting started page: ' + WebGettingStarted);
- OpenBrowser(WebGettingStarted);
- end;
- procedure CurStepChanged(CurStep: TSetupStep);
- var
- ShowCmd: Integer;
- OpenGettingStarted: Boolean;
- UsageData: string;
- CanPostInstallRuns: Boolean;
- Installations: Cardinal;
- begin
- if CurStep = ssPostInstall then
- begin
- Log('Post install');
- InstallationDone := True;
- end
- else
- if CurStep = ssDone then
- begin
- Log('Done');
- // bug in InnoSetup causes it using ssDone even when
- // setup failed because machine was not restarted to complete previous
- // installation. double check that ssPostInstall was called
- if InstallationDone then
- begin
- CanPostInstallRuns := (not WizardSilent) and (not WillRestart);
- OpenGettingStarted :=
- OpenGettingStartedCheckbox.Enabled and
- OpenGettingStartedCheckbox.Checked;
- UsageData := '/Usage=';
- // old style counter
- UsageData := UsageData + Format('TypicalInstallation:%d,', [Integer(IsTypicalInstallation)]);
- UsageData := UsageData + 'InstallationsUser+,';
- Installations := 0; // default, if the counter does not exist
- RegQueryDWordValue(HKEY_LOCAL_MACHINE, '{#RegistryKey}', 'Installations', Installations);
- Inc(Installations);
- if not RegWriteDWordValue(HKEY_LOCAL_MACHINE, '{#RegistryKey}', 'Installations', Installations) then
- begin
- Log('Cannot increment administrator installations counter, probably a non-elevated installation');
- end;
- // new style counters
- if not Upgrade then
- begin
- if IsTypicalInstallation then
- UsageData := UsageData + 'InstallationsFirstTypical+,'
- else
- UsageData := UsageData + 'InstallationsFirstCustom+,';
- end
- else
- begin
- if AutomaticUpdate then
- UsageData := UsageData + 'InstallationsUpgradeAutomatic+,'
- else if IsTypicalInstallation then
- UsageData := UsageData + 'InstallationsUpgradeTypical+,'
- else
- UsageData := UsageData + 'InstallationsUpgradeCustom+,';
- end;
- UsageData := UsageData + Format('LastInstallationAutomaticUpgrade:%d,', [Integer(AutomaticUpdate)]);
- if (InitDir <> '') and (InitDir <> WizardForm.DirEdit.Text) then
- UsageData := UsageData + 'InstallationsCustomDir+,';
- if (InitComponents <> '') and (InitComponents <> SaveCheckListBoxState(WizardForm.ComponentsList)) then
- UsageData := UsageData + 'InstallationsCustomComponents+,';
- if (InitTasks <> '') and (InitTasks <> SaveCheckListBoxState(WizardForm.TasksList)) then
- UsageData := UsageData + 'InstallationsCustomTasks+,';
- if (InitInterface >= 0) and (InitInterface <> Integer(CommanderRadioButton.Checked)) then
- UsageData := UsageData + 'InstallationsCustomInterface+,';
- if CanPostInstallRuns and OpenGettingStarted then
- UsageData := UsageData + 'InstallationsGettingStarted+,';
- if CanPostInstallRuns and LaunchCheckbox.Checked then
- UsageData := UsageData + 'InstallationsLaunch+,';
- if WizardSilent then
- UsageData := UsageData + 'InstallationsSilent+,';
- if AskedRestart then
- UsageData := UsageData + 'InstallationsNeedRestart+,';
- if WillRestart then
- UsageData := UsageData + 'InstallationsRestart+,';
- if Donated then
- UsageData := UsageData + 'InstallationsDonate+,';
- if not IsAdminInstallMode then
- UsageData := UsageData + 'InstallationsNonElevated+,';
- // have to do this before running WinSCP GUI instance below,
- // otherwise it loads the empty/previous counters and overwrites our changes,
- // when it's closed
- Log('Recording installer usage statistics: ' + UsageData);
- // make sure we write the counters using the "normal" account
- // (the account that will be used to report the counters)
- ExecApp(UsageData, SW_HIDE, ewWaitUntilTerminated);
- if AutomaticUpdate then
- begin
- Log('Launching WinSCP after automatic update');
- ExecApp('', SW_SHOWNORMAL, ewNoWait);
- if CmdLineParamExists('/OpenGettingStarted') then
- begin
- OpenBrowserGettingStarted;
- end;
- end
- else
- if CanPostInstallRuns then
- begin
- if OpenGettingStarted then
- begin
- OpenBrowserGettingStarted;
- end;
- if LaunchCheckbox.Checked then
- begin
- if OpenGettingStarted then
- begin
- Log('Will launch WinSCP minimized');
- ShowCmd := SW_SHOWMINIMIZED
- end
- else
- begin
- ShowCmd := SW_SHOWNORMAL;
- end;
- Log('Launching WinSCP');
- ExecApp('', ShowCmd, ewNoWait);
- end;
- end;
- end;
- end;
- end;
- #ifdef Sponsor
- function CryptStringToBinary(
- sz: string; cch: LongWord; flags: LongWord; binary: string; var size: LongWord;
- skip: LongWord; flagsused: LongWord): Integer;
- external '[email protected] stdcall';
- const
- CRYPT_STRING_HEX = $04;
- SHCONTCH_NOPROGRESSBOX = 4;
- SHCONTCH_RESPONDYESTOALL = 16;
- var
- ShowSponsor: Integer;
- procedure SponsorImageClick(Sender: TObject);
- begin
- SponsorStatus := 'C';
- OpenBrowser('{#WebReport}?mode=sponsor' + Format('&sponsor=%s&', [Sponsor]) + ExpandConstant('{#WebArguments}'));
- end;
- function CheckSponsorReq: Boolean;
- var
- R, Succeeded: Integer;
- Lines: TStrings;
- I, P: Integer;
- L, Key, Value: string;
- Stream: TStream;
- Buffer: string;
- Size: LongWord;
- ZipPath, TargetPath, ImagePath: string;
- Shell, ZipFile, TargetFolder: Variant;
- SponsorLinkLabel, SponsoringLinkLabel: TLabel;
- SponsorImage: TBitmapImage;
- ImageSize, GrayHeight: Integer;
- begin
- if ShowSponsor = 0 then
- begin
- SponsorImage := nil;
- Log('Checking for response to sponsor request');
- try
- Succeeded := 0;
- // Not testing return value, as it always returns -1 for some reason
- R := SponsorReq.WaitForResponse(1, Succeeded);
- if R = 0 then
- begin
- Log('Timed out waiting for a response to sponsor request');
- SponsorStatus := 'T';
- ShowSponsor := -1;
- end
- else
- if SponsorReq.Status <> 200 then
- begin
- Log('Sponsor request failed with HTTP error: ' + IntToStr(SponsorReq.Status) + ' ' + SponsorReq.StatusText);
- SponsorStatus := 'H';
- ShowSponsor := -1;
- end
- else
- begin
- Log('Sponsor request succeeded');
- SponsorLinkLabel := TLabel.Create(SponsorPage);
- SponsorLinkLabel.Parent := SponsorPage.Surface;
- SponsorLinkLabel.Caption := 'Visit release sponsor';
- SponsorLinkLabel.Top := SponsorPage.Surface.Height - SponsorLinkLabel.Height - ScaleY(2);
- SponsorLinkLabel.OnClick := @SponsorImageClick;
- LinkLabel(SponsorLinkLabel);
- SponsoringLinkLabel := TLabel.Create(SponsorPage);
- SponsoringLinkLabel.Parent := SponsorPage.Surface;
- SponsoringLinkLabel.Caption := 'Become next release sponsor';
- SponsoringLinkLabel.Top := SponsorLinkLabel.Top;
- SponsoringLinkLabel.OnClick := @SponsoringLinkLabelClick;
- LinkLabel(SponsoringLinkLabel);
- Lines := TStringList.Create;
- try
- Lines.Text := SponsorReq.ResponseText;
- for I := 0 to Lines.Count - 1 do
- begin
- L := Lines[I];
- P := Pos('=', L);
- if P = 0 then
- begin
- Log('Malformed sponsor response directive: ' + L);
- SponsorStatus := 'P';
- ShowSponsor := -1;
- break;
- end
- else
- begin
- Key := Trim(Copy(L, 1, P - 1));
- Value := Trim(Copy(L, P + 1, Length(L) - P));
- if CompareText(Key, 'result') = 0 then
- begin
- if Value <> '-' then
- begin
- Log('No sponsor returned');
- SponsorStatus := Copy(Value, 1, 1);
- ShowSponsor := -1;
- break;
- end
- else
- begin
- Log('Sponsor returned');
- end;
- end
- else
- if (CompareText(Key, 'image') = 0) or
- (CompareText(Key, 'localimage') = 0) then
- begin
- if CompareText(Key, 'localimage') = 0 then
- begin
- Log(Format('Extracting embedded sponsor image (%s)', [Value]));
- ExtractTemporaryFile(Value);
- ImagePath := ExpandConstant('{tmp}\' + Value);
- end
- else
- begin
- Log(Format('Extracting returned sponsor image (%d bytes)', [Length(Value)]));
- ZipPath := ExpandConstant('{tmp}\sponsor.zip');
- Stream := TFileStream.Create(ZipPath, fmCreate);
- try
- SetLength(Buffer, (Length(Value) div 4) + 1);
- Size := Length(Value) div 2;
- if (CryptStringToBinary(Value, Length(Value), CRYPT_STRING_HEX, Buffer, Size, 0, 0) = 0) or
- (Size <> Length(Value) div 2) then
- begin
- Log('Error decoding binary string');
- SponsorStatus := 'P';
- ShowSponsor := -1;
- break;
- end;
- Stream.WriteBuffer(Buffer, Size);
- finally
- Stream.Free;
- end;
- Shell := CreateOleObject('Shell.Application');
- ZipFile := Shell.NameSpace(ZipPath);
- if VarIsClear(ZipFile) then
- begin
- RaiseException(Format('ZIP file "%s" does not exist or cannot be opened', [ZipPath]));
- end
- else
- begin
- TargetPath := ExpandConstant('{tmp}');
- TargetFolder := Shell.NameSpace(TargetPath);
- if VarIsClear(TargetFolder) then
- begin
- RaiseException(Format('Target path "%s" does not exist', [TargetPath]));
- end
- else
- begin
- TargetFolder.CopyHere(ZipFile.Items, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
- ImagePath := ExpandConstant('{tmp}\sponsor.bmp');
- end;
- end;
- end;
- SponsorImage := TBitmapImage.Create(SponsorPage);
- SponsorImage.Parent := SponsorPage.Surface;
- SponsorImage.AutoSize := True;
- SponsorImage.Hint := SponsorLinkLabel.Caption;
- SponsorImage.ShowHint := True;
- try
- LoadBitmap(SponsorImage, ImagePath, SponsorPage.Surface.Color);
- except
- Log('Error loading sponsor image: ' + GetExceptionMessage);
- SponsorStatus := 'I';
- ShowSponsor := -1;
- end;
- if ShowSponsor = 0 then
- begin
- GrayHeight :=
- // Overal height of area between header and footer (InnerNotebook is smaller and not vertically centered)
- (WizardForm.Bevel.Top - (WizardForm.OuterNotebook.Top + GetBottom(WizardForm.Bevel1)))
- // Bottom padding of InnerNotebook
- - (WizardForm.Bevel.Top - GetBottom(WizardForm.InnerNotebook))
- // height occupied by link label on the bottom of InnerNotebook
- - SponsorLinkLabel.Height;
- SponsorImage.Top := ((GrayHeight - SponsorImage.Height) div 2) - (WizardForm.InnerNotebook.Top - GetBottom(WizardForm.Bevel1));
- if SponsorImage.Top < 0 then SponsorImage.Top := 0;
- SponsorImage.Left := (SponsorPage.Surface.Width - SponsorImage.Width) div 2;
- SponsorLinkLabel.Left := SponsorImage.Left;
- if SponsorLinkLabel.Left < 0 then SponsorLinkLabel.Left := 0;
- SponsoringLinkLabel.Left := GetRight(SponsorImage) - SponsoringLinkLabel.Width;
- if GetRight(SponsoringLinkLabel) > SponsorPage.Surface.Width then
- SponsoringLinkLabel.Left := SponsorPage.Surface.Width - SponsoringLinkLabel.Width;
- SponsorImage.Cursor := crHand;
- SponsorImage.OnClick := @SponsorImageClick;
- FileSize(ImagePath, ImageSize);
- Log(Format('Sponsor image loaded (%d bytes, %dx%d)', [Integer(ImageSize), SponsorPage.Surface.Width, SponsorImage.Height]));
- end;
- end
- else
- if CompareText(Key, 'sponsor') = 0 then
- begin
- Sponsor := Value;
- end
- else
- if CompareText(Key, 'description') = 0 then
- begin
- SponsorPage.Description := Value;
- Log('Sponsor page description: ' + Value);
- end
- else
- if CompareText(Key, 'caption') = 0 then
- begin
- SponsorPage.Caption := Value;
- Log('Sponsor page caption: ' + Value);
- end
- else
- if CompareText(Key, 'sponsor_caption') = 0 then
- begin
- SponsorLinkLabel.Caption := Value;
- Log('Sponsor link caption: ' + Value);
- end
- else
- if CompareText(Key, 'sponsoring_caption') = 0 then
- begin
- if Value = '' then
- begin
- SponsoringLinkLabel.Visible := False;
- Log('Hiding sponsoring link');
- end
- else
- begin
- SponsoringLinkLabel.Caption := Value;
- Log('Sponsoring link caption: ' + Value);
- end;
- end
- else
- begin
- Log('Unknown sponsor directive: ' + Key);
- end;
- end;
- end;
- finally
- Lines.Free;
- end;
- if ShowSponsor = 0 then
- begin
- if SponsorImage = nil then
- begin
- Log('Incomplete sponsor data');
- SponsorStatus := 'P';
- ShowSponsor := -1;
- end
- else
- begin
- SponsorStatus := 'S';
- ShowSponsor := 1;
- end;
- end;
- end;
- except
- Log('Error processing response to sponsor request: ' + GetExceptionMessage);
- SponsorStatus := 'E';
- ShowSponsor := -1;
- end;
- end;
- Result := (ShowSponsor > 0);
- end;
- #endif
- function ShouldSkipPage(PageID: Integer): Boolean;
- begin
- Result :=
- { Hide most pages during typical installation }
- (IsTypicalInstallation and
- ((PageID = wpSelectDir) or (PageID = wpSelectComponents) or
- (PageID = wpSelectTasks) or
- { Hide Interface page for upgrades only, show for fresh installs }
- ((PageID = InterfacePage.ID) and Upgrade)))
- #ifdef Sponsor
- or
- ((SponsorPage <> nil) and (PageID = SponsorPage.ID) and (not CheckSponsorReq))
- #endif
- ;
- end;
- function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo,
- MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: string): string;
- var
- S: string;
- S2: string;
- begin
- S := '';
- S := S + MemoDirInfo + NewLine + NewLine;
- if not Upgrade then
- begin
- if IsTypicalInstallation then S2 := CustomMessage('TypicalType')
- else S2 := CustomMessage('CustomType');
- end
- else
- begin
- if IsTypicalInstallation then S2 := CustomMessage('TypicalUpgradeType')
- else S2 := CustomMessage('CustomUpgradeType');
- end;
- StringChange(S2, '&', '');
- S := S + SetupMessage(msgReadyMemoType) + NewLine + Space + S2 + NewLine + NewLine;
- S := S + MemoComponentsInfo + NewLine + NewLine;
- if Length(MemoGroupInfo) > 0 then
- S := S + MemoGroupInfo + NewLine + NewLine;
- if Length(MemoTasksInfo) > 0 then
- S := S + MemoTasksInfo + NewLine + NewLine;
- S := S + CustomMessage('UserSettingsOverview') + NewLine;
- S := S + Space;
- if CommanderRadioButton.Checked then S2 := CustomMessage('NortonCommanderInterfaceC')
- else S2 := CustomMessage('ExplorerInterfaceC');
- StringChange(S2, '&', '');
- S := S + S2;
- S := S + NewLine;
- Result := S;
- end;
- function InitializeUninstall: Boolean;
- begin
- // let application know that we are running silent uninstall,
- // this turns UninstallCleanup to noop
- if UninstallSilent then
- CreateMutex('WinSCPSilentUninstall');
- Result := True;
- end;
- function HasUserPrograms: Boolean;
- begin
- // To avoid the installer failing when the {userprograms}
- // cannot be resolved (when installing via system account or SCCM)
- try
- ExpandConstant('{userprograms}');
- Log('Have user programs');
- Result := True;
- except
- Log('Does not have user programs');
- Result := False;
- end;
- end;
- #expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")
|