winscpsetup.iss 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505
  1. #define AppId "winscp3"
  2. #define ParentRegistryKey "Software\Martin Prikryl"
  3. #define RegistryKey ParentRegistryKey+"\WinSCP 2"
  4. #define DefaultLang "en"
  5. #define WebRoot "http://winscp.net/"
  6. #define WebForum WebRoot+"forum/"
  7. #define WebDocumentation WebRoot+"eng/docs/"
  8. #define WebReport WebRoot+"install.php"
  9. #define WebPuTTY "http://www.chiark.greenend.org.uk/~sgtatham/putty/"
  10. #define Year 2012
  11. #define EnglishLang "English"
  12. #define SetupTypeData "SetupType"
  13. #define InnoSetupReg "Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppId + "_is1"
  14. #define InnoSetupAppPathReg "Inno Setup: App Path"
  15. #ifndef PuttySourceDir
  16. #define PuttySourceDir "c:\Program Files\PuTTY"
  17. #endif
  18. #ifndef Status
  19. #define Status "unofficial"
  20. #endif
  21. #ifndef SourceDir
  22. #define SourceDir ".."
  23. #endif
  24. #ifndef BinariesDir
  25. #define BinariesDir "..\Release"
  26. #endif
  27. #ifndef OutputSuffix
  28. #define OutputSuffix
  29. #endif
  30. #ifndef AllTranslations
  31. #define AllTranslations
  32. #endif
  33. #define TranslationDirRel "translations"
  34. #define TranslationDir "translations"
  35. #define OutputDir "."
  36. #define TranslationFileMask "WinSCP.???"
  37. #define MainFileName "WinSCP.exe"
  38. #define MainFileSource BinariesDir+"\"+MainFileName
  39. #define ShellExtFileSource BinariesDir+"\DragExt.dll"
  40. #define ShellExt64FileSource BinariesDir+"\DragExt64.dll"
  41. #define ConsoleFileSource BinariesDir+"\WinSCP.com"
  42. #define IconFileSource SourceDir+"\resource\Icon256.ico"
  43. #ifdef Donations
  44. #define PayPalCardImage "paypalcard.bmp"
  45. #endif
  46. #define Major
  47. #define Minor
  48. #define Rev
  49. #define Build
  50. #expr ParseVersion(MainFileSource, Major, Minor, Rev, Build)
  51. #define VersionOnly Str(Major)+"."+Str(Minor)+(Rev > 0 ? "."+Str(Rev) : "")
  52. #define Version VersionOnly+(Status != "" ? " "+Status : "")
  53. #define WebArguments "ver=" +VersionOnly + "&lang={language}&utm_source=winscp&utm_medium=setup&utm_campaign=" + VersionOnly
  54. #define WebGettingStarted WebRoot + "eng/installed.php?" + WebArguments + "&prevver="
  55. #ifdef OpenCandy
  56. #include "opencandy\OCSetupHlp.iss"
  57. #endif
  58. ; Some features of ISCC requires path relative to script,
  59. ; some path relative to CWD
  60. #define MessagesPathRel(L) TranslationDirRel + "\" + "WinSCP." + L + ".isl"
  61. #ifdef Chrome
  62. #define ChromeLogoFile "chromelogo.bmp"
  63. #define ChromeAdFile "chromead.bmp"
  64. #define ChromeGcApiDllFile "gcapi_dll.dll"
  65. #define ChromeCheckerFile "chromech.exe"
  66. #define ChromeInstallerFile "WinSCP_Chrome.exe"
  67. #define ChromeBrandCode1 "WSCA"
  68. #define ChromeBrandCode2 "WSCB"
  69. #include "chrome\texts.iss"
  70. #endif
  71. [Setup]
  72. AppId={#AppId}
  73. AppName=WinSCP
  74. AppMutex=WinSCP
  75. AppPublisher=Martin Prikryl
  76. AppPublisherURL={#WebRoot}
  77. AppSupportURL={#WebForum}
  78. AppUpdatesURL={#WebRoot}eng/download.php
  79. VersionInfoCompany=Martin Prikryl
  80. VersionInfoDescription=Setup for WinSCP {#Version} (SFTP, FTP and SCP client)
  81. VersionInfoVersion={#Major}.{#Minor}.{#Rev}.{#Build}
  82. VersionInfoTextVersion={#Version}
  83. VersionInfoCopyright=(c) 2000-{#Year} Martin Prikryl
  84. DefaultDirName={pf}\WinSCP
  85. DefaultGroupName=WinSCP
  86. AllowNoIcons=yes
  87. #ifdef Chrome
  88. LicenseFile=licence.setup-chrome.txt
  89. #else
  90. LicenseFile=licence.setup.txt
  91. #endif
  92. UninstallDisplayIcon={app}\WinSCP.exe
  93. OutputDir={#OutputDir}
  94. DisableStartupPrompt=yes
  95. AppVersion={#Version}
  96. AppVerName=WinSCP {#Version}
  97. OutputBaseFilename=winscp{#Major}{#Minor}{#Rev}setup{#OutputSuffix}
  98. SolidCompression=yes
  99. ShowTasksTreeLines=yes
  100. PrivilegesRequired=none
  101. UsePreviousLanguage=yes
  102. #ifdef Sign
  103. SignTool=sign $f "WinSCP Installer" http://winscp.net/eng/docs/installation
  104. #endif
  105. #ifdef Chrome
  106. RestartIfNeededByRun=no
  107. #endif
  108. [Languages]
  109. Name: {#DefaultLang}; MessagesFile: {#MessagesPathRel(DefaultLang)}
  110. #define FindHandle
  111. #dim Languages[200]
  112. #define LanguageCount 0
  113. #define AnyLanguageComplete 0
  114. #define LangI
  115. #define Complete
  116. #define DirName
  117. #define DirNameRel
  118. #sub ProcessTranslationFile
  119. #define FileName FindGetFileName(FindHandle)
  120. #define Lang Copy(FileName, Pos(".", FileName)+1)
  121. #define MessagesPath DirName + "\" + "WinSCP." + Lang + ".isl"
  122. #define LangNameFull ReadIni(MessagesPath, "LangOptions", "LanguageName")
  123. #define Sep Pos(" - ", LangNameFull)
  124. #if Sep > 0
  125. #define LangName Copy(LangNameFull, 1, Sep - 1)
  126. #else
  127. #define LangName LangNameFull
  128. #endif
  129. #define LangID ReadIni(MessagesPath, "LangOptions", "LanguageID")
  130. #expr Languages[LanguageCount*4] = Lang
  131. #expr Languages[LanguageCount*4+1] = LangName
  132. #expr Languages[LanguageCount*4+2] = LangID
  133. #expr Languages[LanguageCount*4+3] = Complete
  134. #expr LanguageCount++
  135. #if Complete == 1
  136. Name: {#Lang}; MessagesFile: {#MessagesPathRel(Lang)}
  137. #expr AnyLanguageComplete = 1
  138. #endif
  139. #endsub /* sub ProcessTranslationFile */
  140. #sub ProcessTranslationDir
  141. #if FindHandle = FindFirst(DirNameRel + "\" + TranslationFileMask, 0)
  142. #define FResult 1
  143. #for {0; FResult; FResult = FindNext(FindHandle)} ProcessTranslationFile
  144. #expr FindClose(FindHandle)
  145. #endif
  146. #endsub /* sub ProcessTranslationDir */
  147. #expr Complete = 1
  148. #expr DirName = TranslationDir
  149. #expr DirNameRel = TranslationDirRel
  150. #emit ProcessTranslationDir
  151. #ifdef TranslationIncompleteDir
  152. #expr Complete = 0
  153. #expr DirName = TranslationIncompleteDir
  154. #expr DirNameRel = TranslationIncompleteDirRel
  155. #emit ProcessTranslationDir
  156. #endif
  157. ; Types are not used anymore, they are preserved only to let setup
  158. ; detect previous installation type and decide between typical/custom setup
  159. [Types]
  160. Name: full; Description: "full"
  161. Name: compact; Description: "compact"
  162. Name: custom; Description: "custom"; Flags: iscustom
  163. [Components]
  164. Name: main; Description: {cm:ApplicationComponent}; \
  165. Types: full custom compact; Flags: fixed
  166. Name: shellext; Description: {cm:ShellExtComponent}; \
  167. Types: full compact
  168. Name: pageant; Description: {cm:PageantComponent}; \
  169. Types: full
  170. Name: puttygen; Description: {cm:PuTTYgenComponent}; \
  171. Types: full
  172. #if AnyLanguageComplete == 1
  173. Name: transl; Description: {cm:TranslationsComponent}; \
  174. Types: full
  175. #endif
  176. [Tasks]
  177. Name: enableupdates; Description: {cm:EnableUpdates}
  178. Name: enableupdates\enablecollectusage; Description: {cm:EnableCollectUsage}
  179. ; Windows integration
  180. Name: desktopicon; Description: {cm:DesktopIconTask}
  181. Name: desktopicon\user; Description: {cm:DesktopIconUserTask}; \
  182. Flags: exclusive unchecked
  183. Name: desktopicon\common; Description: {cm:DesktopIconCommonTask}; \
  184. Flags: exclusive
  185. ; No Quick Launch on Win7
  186. Name: quicklaunchicon; Description: {cm:QuickLaunchIconTask}; \
  187. Flags: unchecked; OnlyBelowVersion: 0,6.1.7600
  188. Name: sendtohook; Description: {cm:SendToHookTask}
  189. Name: urlhandler; Description: {cm:RegisterAsUrlHandler}
  190. Name: searchpath; Description: {cm:AddSearchPath}; \
  191. Flags: unchecked; Check: IsAdminLoggedOn
  192. [Icons]
  193. ; This is created always (unless user checks Don't create a Start menu folder,
  194. ; Setup\AllowNoIcons=yes)
  195. Name: "{group}\WinSCP"; Filename: "{app}\WinSCP.exe"; Components: main; \
  196. Comment: "{cm:ProgramComment}"; Check: not IsWin8
  197. ; This is created when pageant/puttygen component is selected (unless user
  198. ; checks Don't create a Start menu folder, Setup\AllowNoIcons=yes).
  199. Name: "{group}\{cm:RSAKeyTools}\PuTTYgen"; \
  200. Filename: "{app}\PuTTY\puttygen.exe"; Components: puttygen; Check: not IsWin8
  201. Name: "{group}\{cm:RSAKeyTools}\Pageant"; \
  202. Filename: "{app}\PuTTY\pageant.exe"; Components: pageant; Check: not IsWin8
  203. ; On Windows 8, create just top-level icon
  204. Name: "{commonstartmenu}\Programs\WinSCP"; Filename: "{app}\WinSCP.exe"; Components: main; \
  205. Comment: "{cm:ProgramComment}"; Check: IsWin8
  206. ; This is created when desktopicon task is selected
  207. Name: "{userdesktop}\WinSCP"; Filename: "{app}\WinSCP.exe"; \
  208. Tasks: desktopicon\user
  209. Name: "{commondesktop}\WinSCP"; Filename: "{app}\WinSCP.exe"; \
  210. Tasks: desktopicon\common
  211. ; This is created when quicklaunchicon task is selected
  212. Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\WinSCP"; \
  213. Filename: "{app}\WinSCP.exe"; Tasks: quicklaunchicon
  214. ; This is created when sendtohook task is selected
  215. Name: "{sendto}\{cm:SendToHookNew}"; Filename: "{app}\WinSCP.exe"; \
  216. Parameters: "/upload"; Tasks: sendtohook
  217. [InstallDelete]
  218. Type: files; Name: "{app}\licence"
  219. Type: files; Name: "{group}\{cm:WebSite}.url"
  220. Type: files; Name: "{group}\{cm:SupportForum}.url"
  221. Type: files; Name: "{group}\{cm:DocumentationPage}.url"
  222. Type: files; Name: "{group}\{cm:RSAKeyTools}\{cm:PuTTYgenManual}.lnk"
  223. Type: files; Name: "{group}\{cm:RSAKeyTools}\{cm:PageantManual}.lnk"
  224. Type: files; Name: "{group}\{cm:RSAKeyTools}\{cm:PuttyWebSite}.url"
  225. ; Legacy sendto hook (SCP-only), only english link is removed
  226. Type: files; Name: "{sendto}\WinSCP3 (upload using SCP).lnk"
  227. Type: files; Name: "{group}\{cm:RSAKeyTools}\{cm:KeysManual}.lnk"
  228. Type: files; Name: "{app}\{cm:SupportForum}.url"
  229. Type: files; Name: "{app}\{cm:DocumentationPage}.url"
  230. Type: files; Name: "{app}\WinSCP.url"
  231. Type: files; Name: "{app}\PuTTY\PuTTY.url"
  232. ; Remove links to winscp3
  233. Type: files; Name: "{app}\WinSCP3.exe"
  234. Type: files; Name: "{app}\WinSCP3.com"
  235. Type: files; Name: "{group}\WinSCP3.lnk"
  236. Type: files; Name: "{userdesktop}\WinSCP3.lnk"
  237. Type: files; Name: "{commondesktop}\WinSCP3.lnk"
  238. Type: files; Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\WinSCP3.lnk"
  239. Type: files; Name: "{sendto}\{cm:SendToHook}.lnk"
  240. [Run]
  241. ; This is called when urlhandler task is selected
  242. Filename: "{app}\WinSCP.exe"; Parameters: "/RegisterAsUrlHandler"; \
  243. StatusMsg: {cm:RegisteringAsUrlHandler}; Tasks: urlhandler
  244. Filename: "{app}\WinSCP.exe"; Parameters: "/AddSearchPath"; \
  245. StatusMsg: {cm:AddingSearchPath}; Tasks: searchpath
  246. #ifdef Chrome
  247. Filename: "{tmp}\{#ChromeInstallerFile}"; \
  248. Parameters: "/r1:{#ChromeBrandCode1} /r2:{#ChromeBrandCode2} /b:1"; \
  249. StatusMsg: {cm:ChromeInstalling}; \
  250. Check: IsChromeSelected and IsChromeDefaultSelected
  251. Filename: "{tmp}\{#ChromeInstallerFile}"; \
  252. Parameters: "/r1:{#ChromeBrandCode1} /r2:{#ChromeBrandCode2} /b:0"; \
  253. StatusMsg: {cm:ChromeInstalling}; \
  254. Check: IsChromeSelected and (not IsChromeDefaultSelected)
  255. #endif
  256. [UninstallDelete]
  257. ; These additional files are created by application
  258. Type: files; Name: "{app}\WinSCP.ini"
  259. Type: files; Name: "{app}\WinSCP.cgl"
  260. ; WinSCP3 may remain from previous version, note that we do not delete it on
  261. ; upgrade, only duplicate into WinSCP.ini, see [Files]
  262. Type: files; Name: "{app}\WinSCP3.ini"
  263. [Files]
  264. Source: "{#MainFileSource}"; DestDir: "{app}"; \
  265. Components: main; Flags: ignoreversion
  266. ; If WinSCP3.ini already exists on target system, copy it into WinSCP.ini
  267. ; (if WinSCP.ini does not exist yet)
  268. Source: "{app}\WinSCP3.ini"; DestName: "WinSCP.ini"; DestDir: "{app}"; \
  269. Components: main; Flags: ignoreversion external skipifsourcedoesntexist onlyifdoesntexist
  270. Source: "{#ConsoleFileSource}"; DestDir: "{app}"; \
  271. Components: main; Flags: ignoreversion
  272. Source: "licence.txt"; DestDir: "{app}"; \
  273. Components: main; Flags: ignoreversion
  274. Source: "{#ShellExtFileSource}"; DestDir: "{app}"; \
  275. Components: shellext; \
  276. Flags: regserver restartreplace uninsrestartdelete; \
  277. Check: not IsWin64
  278. Source: "{#ShellExt64FileSource}"; DestDir: "{app}"; \
  279. Components: shellext; \
  280. Flags: regserver restartreplace uninsrestartdelete; \
  281. Check: IsWin64
  282. Source: "{#PuttySourceDir}\LICENCE"; DestDir: "{app}\PuTTY"; \
  283. Components: pageant puttygen; Flags: ignoreversion
  284. Source: "{#PuttySourceDir}\putty.hlp"; DestDir: "{app}\PuTTY"; \
  285. Components: pageant puttygen; Flags: ignoreversion
  286. Source: "{#PuttySourceDir}\pageant.exe"; DestDir: "{app}\PuTTY"; \
  287. Components: pageant; Flags: ignoreversion
  288. Source: "{#PuttySourceDir}\puttygen.exe"; DestDir: "{app}\PuTTY"; \
  289. Components: puttygen; Flags: ignoreversion
  290. #ifdef Donations
  291. Source: "{#PayPalCardImage}"; \
  292. Flags: dontcopy
  293. #endif
  294. #ifdef OpenCandy
  295. Source: "{#OC_OCSETUPHLP_FILE_PATH}"; \
  296. Flags: dontcopy ignoreversion deleteafterinstall
  297. #endif
  298. #ifdef Chrome
  299. Source: "chrome\{#ChromeLogoFile}"; Flags: dontcopy
  300. Source: "chrome\{#ChromeAdFile}"; Flags: dontcopy
  301. Source: "chrome\{#ChromeGcApiDllFile}"; Flags: dontcopy
  302. Source: "chrome\{#ChromeCheckerFile}"; Flags: dontcopy
  303. Source: "chrome\{#ChromeInstallerFile}"; DestDir: "{tmp}"; \
  304. Flags: deleteafterinstall; Check: IsChromeSelected
  305. #endif
  306. [Registry]
  307. Root: HKCU; Subkey: "{#ParentRegistryKey}"; Flags: uninsdeletekeyifempty
  308. Root: HKCU; Subkey: "{#RegistryKey}"; Flags: uninsdeletekeyifempty
  309. ; Norton Commander interface
  310. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
  311. ValueName: "Interface"; ValueData: 0; Check: UserSettings(1)
  312. Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
  313. ValueName: "DefaultInterfaceInterface"; ValueData: 0; \
  314. Check: UserSettings(1); Flags: noerror
  315. ; Explorer-like interface
  316. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
  317. ValueName: "Interface"; ValueData: 1; Check: not UserSettings(1)
  318. Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
  319. ValueName: "DefaultInterfaceInterface"; ValueData: 1; \
  320. Check: not UserSettings(1); Flags: noerror
  321. ; Advanced tab on login dialog
  322. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
  323. ValueName: "ShowAdvancedLoginOptions"; ValueData: 0; Check: not UserSettings(2)
  324. Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
  325. ValueName: "DefaultInterfaceShowAdvancedLoginOptions"; ValueData: 0; \
  326. Check: not UserSettings(2); Flags: noerror
  327. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
  328. ValueName: "ShowAdvancedLoginOptions"; ValueData: 1; Check: UserSettings(2)
  329. Root: HKLM; SubKey: "{#RegistryKey}"; ValueType: dword; \
  330. ValueName: "DefaultInterfaceShowAdvancedLoginOptions"; ValueData: 1; \
  331. Check: UserSettings(2); Flags: noerror
  332. ; If installer enabled ddext, let it reset the settings on uninstall,
  333. ; so the default is used on the next run
  334. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; ValueType: dword; \
  335. ValueName: "DDExtEnabled"; ValueData: 1; Components: shellext; \
  336. Flags: uninsdeletevalue
  337. ; This will remove url handler on uninstall
  338. ; (when urlhandler task was selected when installing)
  339. Root: HKCR; Subkey: "SFTP"; Flags: dontcreatekey uninsdeletekey; \
  340. Tasks: urlhandler
  341. Root: HKCR; Subkey: "SCP"; Flags: dontcreatekey uninsdeletekey; \
  342. Tasks: urlhandler
  343. Root: HKCU; Subkey: "Software\Classes\SFTP"; Flags: dontcreatekey uninsdeletekey; \
  344. Tasks: urlhandler
  345. Root: HKCU; Subkey: "Software\Classes\SCP"; Flags: dontcreatekey uninsdeletekey; \
  346. Tasks: urlhandler
  347. ; Updates
  348. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface\Updates"; \
  349. ValueType: dword; ValueName: "Period"; ValueData: 7; \
  350. Tasks: enableupdates; Check: not UpdatesEnabled
  351. Root: HKLM; SubKey: "{#RegistryKey}"; \
  352. ValueType: dword; ValueName: "DefaultUpdatesPeriod"; ValueData: 7; \
  353. Tasks: enableupdates; Flags: noerror
  354. Root: HKLM; SubKey: "{#RegistryKey}"; \
  355. ValueType: dword; ValueName: "DefaultCollectUsage"; ValueData: 1; \
  356. Tasks: enableupdates\enablecollectusage; Flags: noerror
  357. #if AnyLanguageComplete == 1
  358. [Components]
  359. Name: transl\eng; Description: {#EnglishLang}; Types: full custom compact; \
  360. Flags: fixed
  361. #endif
  362. #sub EmitLang
  363. #if Languages[LangI*4+3] == 1
  364. [Components]
  365. Name: transl\{#Languages[LangI*4]}; Description: {#Languages[LangI*4+1]}; \
  366. Types: full compact custom; Check: IsLang('{#Languages[LangI*4]}')
  367. Name: transl\{#Languages[LangI*4]}; Description: {#Languages[LangI*4+1]}; \
  368. Check: not IsLang('{#Languages[LangI*4]}')
  369. [Files]
  370. Source: "{#TranslationDirRel}\WinSCP.{#Languages[LangI*4]}"; DestDir: "{app}"; \
  371. Components: transl\{#Languages[LangI*4]}; Flags: ignoreversion
  372. [Registry]
  373. ; set program default language to setup language, but only if user installs it
  374. Root: HKCU; SubKey: "{#RegistryKey}\Configuration\Interface"; \
  375. ValueType: dword; ValueName: "LocaleSafe"; ValueData: {#Languages[LangI*4+2]}; \
  376. Components: transl\{#Languages[LangI*4]}; Languages: {#Languages[LangI*4]}
  377. #endif
  378. #endsub /* sub EmitLang */
  379. #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang
  380. [UninstallRun]
  381. Filename: "{app}\WinSCP.exe"; Parameters: "/UninstallCleanup"; \
  382. RunOnceId: "UninstallCleanup"
  383. Filename: "{app}\WinSCP.exe"; Parameters: "/RemoveSearchPath"; \
  384. RunOnceId: "RemoveSearchPath"
  385. [Code]
  386. const
  387. wpSetupType = 100;
  388. wpInterface = 101;
  389. #ifdef Chrome
  390. wpChrome = 102;
  391. #endif
  392. NewLine = #13#10;
  393. var
  394. TypicalTypeButton: TRadioButton;
  395. CustomTypeButton: TRadioButton;
  396. CommanderRadioButton: TRadioButton;
  397. ExplorerRadioButton: TRadioButton;
  398. AdditionalOptionsCaption: TLabel;
  399. AdvancedTabsCheckbox: TCheckbox;
  400. LaunchCheckbox: TCheckbox;
  401. OpenGettingStartedCheckbox: TCheckbox;
  402. AreUpdatesEnabled: Boolean;
  403. Upgrade: Boolean;
  404. MissingTranslations: string;
  405. PrevVersion: string;
  406. #ifdef Donations
  407. DonationPanel: TPanel;
  408. #endif
  409. InstallationDone: Boolean;
  410. LicenseAccepted: Boolean;
  411. #ifdef Chrome
  412. ChromeLogoImage: TBitmapImage;
  413. ChromeLogoImageOffset: Integer;
  414. ChromeAdImage: TBitmapImage;
  415. ChromeCheckbox: TCheckbox;
  416. ChromeDefaultCheckbox: TCheckbox;
  417. ChromeLastPolicyText: TLabel;
  418. ChromeAllowed: Boolean;
  419. ChromeLaunched: Boolean;
  420. LaunchChromeCheckbox: TCheckbox;
  421. #endif
  422. procedure ShowMessage(Text: string);
  423. begin
  424. MsgBox(Text, mbInformation, MB_OK);
  425. end;
  426. function IsLang(Lang: string): Boolean;
  427. begin
  428. Result := (Lang = ActiveLanguage);
  429. end;
  430. function IsWin8: Boolean;
  431. var
  432. Version: TWindowsVersion;
  433. begin
  434. GetWindowsVersionEx(Version);
  435. Result :=
  436. (Version.Major > 6) or
  437. ((Version.Major = 6) and (Version.Minor >= 2));
  438. end;
  439. function UpdatesEnabled: Boolean;
  440. begin
  441. Result := AreUpdatesEnabled;
  442. end;
  443. function UserSettings(Settings: Integer): Boolean;
  444. begin
  445. case Settings of
  446. 1: Result := CommanderRadioButton.Checked;
  447. 2: Result := AdvancedTabsCheckbox.Checked;
  448. else Result := False;
  449. end;
  450. end;
  451. function LanguageName(Lang: string; Unknown: string): string;
  452. begin
  453. #sub EmitLang2
  454. if Lang = '{#Languages[LangI*4]}' then Result := '{#Languages[LangI*4+1]}'
  455. else
  456. #endsub /* sub EmitLang2 */
  457. #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang2
  458. Result := Unknown;
  459. end;
  460. function ContainsLanguage(Lang: string): Boolean;
  461. begin
  462. #sub EmitLang3
  463. #if Languages[LangI*4+3] == 1
  464. if (Lang = '{#Languages[LangI*4]}') then Result := True
  465. else
  466. #endif
  467. #endsub /* sub EmitLang3 */
  468. #for {LangI = 0; LangI < LanguageCount; LangI++} EmitLang3
  469. Result := False;
  470. end;
  471. procedure OpenBrowser(Url: string);
  472. var
  473. ErrorCode: Integer;
  474. begin
  475. ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
  476. end;
  477. procedure OpenHelp;
  478. begin
  479. OpenBrowser('{#WebDocumentation}installation?page=' + IntToStr(WizardForm.CurPageID) + '&' + ExpandConstant('{#WebArguments}'));
  480. end;
  481. procedure HelpButtonClick(Sender: TObject);
  482. begin
  483. OpenHelp;
  484. end;
  485. #ifdef Donations
  486. procedure AboutDonationsLinkClick(Sender: TObject);
  487. begin
  488. OpenBrowser('{#WebRoot}eng/donate.php?' + ExpandConstant('{#WebArguments}'));
  489. end;
  490. procedure DonateLinkClick(Sender: TObject);
  491. var
  492. Control: TControl;
  493. begin
  494. Control := TControl(Sender);
  495. OpenBrowser('{#WebRoot}eng/donate.php?amount=' + IntToStr(Control.Tag) + '&currency=' + ExpandConstant('{cm:Currency}') + '&' + ExpandConstant('{#WebArguments}'));
  496. end;
  497. #endif
  498. procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  499. begin
  500. if Key = 112 { VK_F1 } then
  501. begin
  502. OpenHelp;
  503. Key := 0;
  504. end;
  505. end;
  506. procedure CaptionClick(Sender: TObject);
  507. begin
  508. WizardForm.ActiveControl := TLabel(Sender).FocusControl;
  509. end;
  510. type
  511. TProcessTranslationEvent = procedure(Lang: string; FileName: string);
  512. procedure CollectNames(Lang: string; FileName: string);
  513. begin
  514. if Length(MissingTranslations) > 0 then
  515. MissingTranslations := MissingTranslations + ', ';
  516. MissingTranslations := MissingTranslations + LanguageName(Lang, Lang);
  517. end;
  518. procedure DeleteTranslation(Lang: string; FileName: string);
  519. begin
  520. DeleteFile(FileName);
  521. end;
  522. procedure ProcessMissingTranslations(OnProcessTranslation: TProcessTranslationEvent);
  523. var
  524. Path: string;
  525. FindRec: TFindRec;
  526. Ext: string;
  527. LExt: string;
  528. begin
  529. Path := AddBackslash(WizardDirValue);
  530. if FindFirst(ExpandConstant(Path + '{#TranslationFileMask}'), FindRec) then
  531. begin
  532. try
  533. repeat
  534. if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
  535. begin
  536. Ext := Uppercase(ExtractFileExt(FindRec.Name));
  537. if Pos('.', Ext) = 1 then
  538. begin
  539. Ext := Uppercase(Copy(Ext, 2, Length(Ext) - 1));
  540. LExt := Lowercase(Ext);
  541. if (Pos('-' + Ext + '-', '-{#AllTranslations}-') > 0) and
  542. not ContainsLanguage(LExt) then
  543. OnProcessTranslation(LExt, Path + FindRec.Name);
  544. end;
  545. end;
  546. until not FindNext(FindRec);
  547. finally
  548. FindClose(FindRec);
  549. end;
  550. end;
  551. end;
  552. function WillRestart: Boolean;
  553. begin
  554. Result := WizardForm.YesRadio.Visible and WizardForm.YesRadio.Checked;
  555. end;
  556. procedure UpdatePostInstallRunCheckboxes(Sender: TObject);
  557. begin
  558. LaunchCheckbox.Enabled := not WillRestart;
  559. OpenGettingStartedCheckbox.Enabled :=
  560. LaunchCheckbox.Enabled
  561. #ifdef Chrome
  562. and
  563. ((not LaunchChromeCheckbox.Visible) or (not LaunchChromeCheckbox.Checked));
  564. LaunchChromeCheckbox.Enabled := LaunchCheckbox.Enabled
  565. #endif
  566. end;
  567. procedure LinkLabel(Control: TLabel);
  568. begin
  569. Control.ParentFont := True;
  570. Control.Font.Style := Control.Font.Style + [fsUnderline];
  571. Control.Font.Color := clBlue;
  572. Control.Cursor := crHand;
  573. end;
  574. #ifdef Donations
  575. procedure CreateDonateLink(Amount: Integer; Row: Integer; Top: Integer);
  576. var
  577. Caption: TLabel;
  578. begin
  579. Caption := TLabel.Create(DonationPanel);
  580. Caption.Left := 0;
  581. Caption.Top := Top + Row * ScaleY(16);
  582. Caption.Tag := Amount;
  583. Caption.Parent := DonationPanel;
  584. Caption.Caption := Format(ExpandConstant('{cm:Donate}'), ['$' + IntToStr(Amount)]);
  585. Caption.OnClick := @DonateLinkClick;
  586. LinkLabel(Caption);
  587. end;
  588. #endif
  589. #ifdef Chrome
  590. procedure LoadEmbededBitmap(Image: TBitmapImage; Name: string);
  591. begin
  592. ExtractTemporaryFile(Name);
  593. Image.Bitmap.LoadFromFile(ExpandConstant('{tmp}\' + Name));
  594. Image.AutoSize := True;
  595. end;
  596. procedure ChromeCheckboxClick(Sender: TObject);
  597. begin
  598. ChromeDefaultCheckbox.Enabled := ChromeCheckbox.Checked;
  599. end;
  600. procedure AddChromePolicyText(S: string; OnLinkClick: TNotifyEvent);
  601. var
  602. Caption: TLabel;
  603. I: Integer;
  604. begin
  605. S := ExpandConstant(S);
  606. if s <> '' then
  607. begin
  608. Caption := TLabel.Create(ChromeDefaultCheckbox.Parent);
  609. if ChromeLastPolicyText <> nil then
  610. begin
  611. Caption.Top := ChromeLastPolicyText.Top;
  612. Caption.Left := ChromeLastPolicyText.Left + ChromeLastPolicyText.Width;
  613. end
  614. else
  615. begin
  616. Caption.Top :=
  617. ChromeDefaultCheckbox.Top + ChromeDefaultCheckbox.Height + ScaleY(4);
  618. end;
  619. Caption.Caption := S;
  620. Caption.Parent := ChromeDefaultCheckbox.Parent;
  621. Caption.Font.Name := 'Arial';
  622. Caption.Font.Size := Caption.Font.Size - 1;
  623. Caption.Tag := 1;
  624. if OnLinkClick <> nil then
  625. begin
  626. Caption.Font.Style := Caption.Font.Style + [fsUnderline];
  627. Caption.Font.Color := clBlue;
  628. Caption.Cursor := crHand;
  629. Caption.OnClick := OnLinkClick;
  630. end;
  631. if Caption.Left + Caption.Width > Caption.Parent.Width then
  632. begin
  633. Caption.Left := 0;
  634. Caption.Top := Caption.Top + Caption.Height;
  635. ChromeAdImage.Top := ChromeAdImage.Top - 1;
  636. ChromeCheckbox.Top := ChromeCheckbox.Top - 3;
  637. ChromeDefaultCheckbox.Top := ChromeDefaultCheckbox.Top - 4;
  638. for I := 0 to Caption.Parent.ControlCount - 1 do
  639. begin
  640. if Caption.Parent.Controls[I].Tag = 1 then
  641. Caption.Parent.Controls[I].Top := Caption.Parent.Controls[I].Top - 5;
  642. end;
  643. if Copy(Caption.Caption, 1, 1) = ' ' then
  644. Caption.Caption := Copy(Caption.Caption, 2, Length(Caption.Caption) - 1);
  645. end;
  646. ChromeLastPolicyText := Caption;
  647. end;
  648. end;
  649. procedure OpenPolicy(S: string);
  650. begin
  651. S := FmtMessage(S, [ExpandConstant('{cm:LanguageISOCode}')]);
  652. OpenBrowser(S);
  653. end;
  654. procedure ChromeTermsOfUseClick(Sender: TObject);
  655. begin
  656. OpenPolicy('http://www.google.com/chrome/intl/%1/eula_text.html');
  657. end;
  658. procedure ChromePrivacyPolicyClick(Sender: TObject);
  659. begin
  660. OpenPolicy('http://www.google.com/chrome/intl/%1/privacy.html');
  661. end;
  662. function IsChromeSelected: Boolean;
  663. begin
  664. Result := ChromeAllowed and ChromeCheckbox.Checked;
  665. end;
  666. function IsChromeDefaultSelected: Boolean;
  667. begin
  668. Result := ChromeAllowed and ChromeDefaultCheckbox.Checked;
  669. end;
  670. #endif
  671. procedure InitializeWizard;
  672. var
  673. DefaultLang: Boolean;
  674. UserInterface: Cardinal;
  675. AdvancedTabs: Cardinal;
  676. UpdatesPeriod: Cardinal;
  677. InterfacePage: TWizardPage;
  678. SetupTypePage: TWizardPage;
  679. Caption: TLabel;
  680. HelpButton: TButton;
  681. #ifdef Donations
  682. PayPalCardImagePath: string;
  683. PayPalCardImage: TBitmapImage;
  684. P: Integer;
  685. #endif
  686. S: string;
  687. #ifdef OpenCandy
  688. OpenCandyNewPageID: Integer;
  689. #endif
  690. #ifdef Chrome
  691. ChromePage: TWizardPage;
  692. ResultCode: Integer;
  693. #endif
  694. begin
  695. InstallationDone := False;
  696. LicenseAccepted := False;
  697. #ifdef Chrome
  698. ChromeLaunched := False;
  699. #endif
  700. DefaultLang := (ActiveLanguage = '{#DefaultLang}');
  701. Upgrade :=
  702. RegQueryStringValue(HKLM, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S) or
  703. RegQueryStringValue(HKCU, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S)
  704. if Upgrade and GetVersionNumbersString(AddBackslash(WizardDirValue) + '{#MainFileName}', PrevVersion) and
  705. (PrevVersion[2] = '.') and (PrevVersion[4] = '.') and (PrevVersion[6] = '.') then
  706. begin
  707. PrevVersion := Copy(PrevVersion, 1, 5);
  708. end;
  709. ProcessMissingTranslations(@CollectNames);
  710. WizardForm.KeyPreview := True;
  711. WizardForm.OnKeyDown := @FormKeyDown;
  712. // to accomodate one more task
  713. WizardForm.TasksList.Height := WizardForm.TasksList.Height + ScaleY(8);
  714. #ifndef Chrome
  715. // allow installation without requiring user to accept licence
  716. WizardForm.LicenseAcceptedRadio.Checked := True;
  717. WizardForm.LicenseAcceptedRadio.Visible := False;
  718. WizardForm.LicenseLabel1.Visible := False;
  719. WizardForm.LicenseNotAcceptedRadio.Visible := False;
  720. WizardForm.LicenseMemo.Top := WizardForm.LicenseLabel1.Top;
  721. WizardForm.LicenseMemo.Height :=
  722. WizardForm.LicenseNotAcceptedRadio.Top +
  723. WizardForm.LicenseNotAcceptedRadio.Height -
  724. WizardForm.LicenseMemo.Top - 5;
  725. #endif
  726. // hide installation types combo
  727. WizardForm.TypesCombo.Visible := False;
  728. WizardForm.ComponentsList.Height :=
  729. WizardForm.ComponentsList.Top + WizardForm.ComponentsList.Height -
  730. WizardForm.TypesCombo.Top;
  731. WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  732. // add help button
  733. HelpButton := TButton.Create(WizardForm);
  734. HelpButton.Parent := WizardForm;
  735. HelpButton.Left :=
  736. WizardForm.ClientWidth -
  737. (WizardForm.CancelButton.Left + WizardForm.CancelButton.Width);
  738. HelpButton.Top := WizardForm.CancelButton.Top;
  739. HelpButton.Width := WizardForm.CancelButton.Width;
  740. HelpButton.Height := WizardForm.CancelButton.Height;
  741. HelpButton.Caption := ExpandConstant('{cm:HelpButton}');
  742. HelpButton.OnClick := @HelpButtonClick;
  743. // installation type page
  744. SetupTypePage := CreateCustomPage(wpLicense,
  745. ExpandConstant('{cm:SetupTypeTitle}'),
  746. ExpandConstant('{cm:SetupTypePrompt}'));
  747. TypicalTypeButton := TRadioButton.Create(SetupTypePage);
  748. if not Upgrade then
  749. S := ExpandConstant('{cm:TypicalType}')
  750. else
  751. S := ExpandConstant('{cm:TypicalUpgradeType}');
  752. TypicalTypeButton.Caption :=
  753. FmtMessage(ExpandConstant('{cm:Recommended}'), [S]);
  754. // check typical install, if typical install was installed before or
  755. // when version without setup type support was installed with
  756. // "full" installation or when there were no installation before
  757. // ("full" installation is default)
  758. TypicalTypeButton.Checked :=
  759. ((GetPreviousData('{#SetupTypeData}', '') = 'typical')) or
  760. ((GetPreviousData('{#SetupTypeData}', '') = '') and
  761. (WizardSetupType(False) = 'full'));
  762. TypicalTypeButton.Left := ScaleX(4);
  763. TypicalTypeButton.Width := SetupTypePage.SurfaceWidth -
  764. TypicalTypeButton.Left;
  765. TypicalTypeButton.Parent := SetupTypePage.Surface;
  766. Caption := TLabel.Create(SetupTypePage);
  767. Caption.WordWrap := True;
  768. if not Upgrade then
  769. begin
  770. if DefaultLang then
  771. S := ExpandConstant('{cm:TypicalType2Eng}')
  772. else
  773. S := FmtMessage(ExpandConstant('{cm:TypicalType2Intl}'), [LanguageName(ActiveLanguage, 'Unknown')]);
  774. Caption.Caption :=
  775. ExpandConstant('{cm:TypicalType1}') + NewLine +
  776. S + NewLine +
  777. ExpandConstant('{cm:TypicalType3}');
  778. end
  779. else
  780. begin
  781. if Length(MissingTranslations) > 0 then
  782. begin
  783. #if AnyLanguageComplete
  784. S := FmtMessage(ExpandConstant('{cm:TypicalUpgradeTypeMissingTransl}'), [MissingTranslations]);
  785. #else
  786. S := ExpandConstant('{cm:TypicalUpgradeTypeNoTransl}');
  787. #endif
  788. S := NewLine + S;
  789. end
  790. else S := '';
  791. Caption.Caption :=
  792. ExpandConstant('{cm:TypicalUpgradeType1}') + S;
  793. end;
  794. Caption.Left := ScaleX(4) + ScaleX(20);
  795. Caption.Width := SetupTypePage.SurfaceWidth - Caption.Left;
  796. Caption.Top := TypicalTypeButton.Top + TypicalTypeButton.Height + ScaleY(6);
  797. Caption.Parent := SetupTypePage.Surface;
  798. Caption.FocusControl := TypicalTypeButton;
  799. Caption.OnClick := @CaptionClick;
  800. CustomTypeButton := TRadioButton.Create(SetupTypePage);
  801. if not Upgrade then
  802. CustomTypeButton.Caption := ExpandConstant('{cm:CustomType}')
  803. else
  804. CustomTypeButton.Caption := ExpandConstant('{cm:CustomUpgradeType}');
  805. CustomTypeButton.Checked := (not TypicalTypeButton.Checked);
  806. CustomTypeButton.Left := ScaleX(4);
  807. CustomTypeButton.Width := SetupTypePage.SurfaceWidth -
  808. CustomTypeButton.Left;
  809. CustomTypeButton.Top := Caption.Top + Caption.Height + ScaleY(10);
  810. CustomTypeButton.Parent := SetupTypePage.Surface;
  811. Caption := TLabel.Create(SetupTypePage);
  812. Caption.WordWrap := True;
  813. if not Upgrade then
  814. begin
  815. Caption.Caption :=
  816. ExpandConstant('{cm:CustomType1}');
  817. end
  818. else
  819. begin
  820. Caption.Caption :=
  821. ExpandConstant('{cm:CustomUpgradeType1}') + NewLine +
  822. ExpandConstant('{cm:CustomUpgradeType2}');
  823. end;
  824. Caption.Left := ScaleX(4) + ScaleX(20);
  825. Caption.Width := SetupTypePage.SurfaceWidth - Caption.Left;
  826. Caption.Top := CustomTypeButton.Top + CustomTypeButton.Height +
  827. ScaleY(6);
  828. Caption.Parent := SetupTypePage.Surface;
  829. Caption.FocusControl := CustomTypeButton;
  830. Caption.OnClick := @CaptionClick;
  831. // interface page
  832. InterfacePage := CreateCustomPage(wpSelectTasks,
  833. ExpandConstant('{cm:UserSettingsTitle}'),
  834. ExpandConstant('{cm:UserSettingsPrompt}'));
  835. UpdatesPeriod := 0;
  836. RegQueryDWordValue(HKCU, '{#RegistryKey}\Configuration\Interface\Updates',
  837. 'Period', UpdatesPeriod);
  838. AreUpdatesEnabled := (UpdatesPeriod <> 0);
  839. UserInterface := 0; { default is commander }
  840. RegQueryDWordValue(HKCU, '{#RegistryKey}\Configuration\Interface',
  841. 'Interface', UserInterface);
  842. AdvancedTabs := 0; { advanced tabs are off by default }
  843. RegQueryDWordValue(HKCU, '{#RegistryKey}\Configuration\Interface',
  844. 'ShowAdvancedLoginOptions', AdvancedTabs);
  845. Caption := TLabel.Create(InterfacePage);
  846. Caption.Caption := ExpandConstant('{cm:UserInterfaceStyle}');
  847. Caption.Width := InterfacePage.SurfaceWidth;
  848. Caption.Parent := InterfacePage.Surface;
  849. CommanderRadioButton := TRadioButton.Create(InterfacePage);
  850. CommanderRadioButton.Caption := ExpandConstant('{cm:NortonCommanderInterfaceB}');
  851. CommanderRadioButton.Checked := (UserInterface = 0);
  852. CommanderRadioButton.Left := ScaleX(4);
  853. CommanderRadioButton.Width := InterfacePage.SurfaceWidth -
  854. CommanderRadioButton.Left;
  855. CommanderRadioButton.Top := Caption.Top + Caption.Height + ScaleY(6);
  856. CommanderRadioButton.Parent := InterfacePage.Surface;
  857. Caption := TLabel.Create(InterfacePage);
  858. Caption.WordWrap := True;
  859. Caption.Caption :=
  860. ExpandConstant('{cm:NortonCommanderInterface1}') + NewLine +
  861. ExpandConstant('{cm:NortonCommanderInterface2}') + NewLine +
  862. ExpandConstant('{cm:NortonCommanderInterface3}');
  863. Caption.Left := ScaleX(4) + ScaleX(20);
  864. Caption.Width := InterfacePage.SurfaceWidth - Caption.Left;
  865. Caption.Top := CommanderRadioButton.Top + CommanderRadioButton.Height +
  866. ScaleY(6);
  867. Caption.Parent := InterfacePage.Surface;
  868. Caption.FocusControl := CommanderRadioButton;
  869. Caption.OnClick := @CaptionClick;
  870. ExplorerRadioButton := TRadioButton.Create(InterfacePage);
  871. ExplorerRadioButton.Caption := ExpandConstant('{cm:ExplorerInterfaceB}');
  872. ExplorerRadioButton.Checked := (UserInterface <> 0);
  873. ExplorerRadioButton.Left := ScaleX(4);
  874. ExplorerRadioButton.Width := InterfacePage.SurfaceWidth -
  875. ExplorerRadioButton.Left;
  876. ExplorerRadioButton.Top := Caption.Top + Caption.Height + ScaleY(10);
  877. ExplorerRadioButton.Parent := InterfacePage.Surface;
  878. Caption := TLabel.Create(InterfacePage);
  879. Caption.WordWrap := True;
  880. Caption.Caption :=
  881. ExpandConstant('{cm:ExplorerInterface1}') + NewLine +
  882. ExpandConstant('{cm:ExplorerInterface2}') + NewLine +
  883. ExpandConstant('{cm:ExplorerInterface3}');
  884. Caption.Left := ScaleX(4) + ScaleX(20);
  885. Caption.Width := InterfacePage.SurfaceWidth - Caption.Left;
  886. Caption.Top := ExplorerRadioButton.Top + ExplorerRadioButton.Height +
  887. ScaleY(6);
  888. Caption.Parent := InterfacePage.Surface;
  889. Caption.FocusControl := ExplorerRadioButton;
  890. Caption.OnClick := @CaptionClick;
  891. AdditionalOptionsCaption := TLabel.Create(InterfacePage);
  892. AdditionalOptionsCaption.Caption := ExpandConstant('{cm:AdditionalOptions}');
  893. AdditionalOptionsCaption.Width := InterfacePage.SurfaceWidth;
  894. AdditionalOptionsCaption.Top := Caption.Top + Caption.Height + ScaleY(10);
  895. AdditionalOptionsCaption.Parent := InterfacePage.Surface;
  896. AdvancedTabsCheckbox := TCheckbox.Create(InterfacePage);
  897. AdvancedTabsCheckbox.Caption := ExpandConstant('{cm:AdvancedLoginOptions}');
  898. AdvancedTabsCheckbox.Checked := (AdvancedTabs <> 0);
  899. AdvancedTabsCheckbox.Left := ScaleX(4);
  900. AdvancedTabsCheckbox.Width := InterfacePage.SurfaceWidth -
  901. AdvancedTabsCheckbox.Left;
  902. AdvancedTabsCheckbox.Top :=
  903. AdditionalOptionsCaption.Top + AdditionalOptionsCaption.Height + ScaleY(6);
  904. AdvancedTabsCheckbox.Parent := InterfacePage.Surface;
  905. // run checkbox
  906. LaunchCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
  907. LaunchCheckbox.Caption := ExpandConstant('{cm:Launch}');
  908. LaunchCheckbox.Checked := True;
  909. LaunchCheckbox.Left := WizardForm.YesRadio.Left;
  910. LaunchCheckbox.Width := WizardForm.YesRadio.Width;
  911. LaunchCheckbox.Parent := WizardForm.FinishedPage;
  912. OpenGettingStartedCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
  913. OpenGettingStartedCheckbox.Caption := ExpandConstant('{cm:OpenGettingStarted}');
  914. OpenGettingStartedCheckbox.Checked := True;
  915. OpenGettingStartedCheckbox.Left := WizardForm.YesRadio.Left;
  916. OpenGettingStartedCheckbox.Width := WizardForm.YesRadio.Width;
  917. OpenGettingStartedCheckbox.Parent := WizardForm.FinishedPage;
  918. #ifdef Chrome
  919. LaunchChromeCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
  920. LaunchChromeCheckbox.Caption := ExpandConstant('{cm:ChromeLaunch}');
  921. LaunchChromeCheckbox.Checked := True;
  922. LaunchChromeCheckbox.Left := WizardForm.YesRadio.Left;
  923. LaunchChromeCheckbox.Width := WizardForm.YesRadio.Width;
  924. LaunchChromeCheckbox.Parent := WizardForm.FinishedPage;
  925. LaunchChromeCheckbox.OnClick := @UpdatePostInstallRunCheckboxes;
  926. #endif
  927. #ifdef Donations
  928. DonationPanel := TPanel.Create(WizardForm.FinishedPage);
  929. DonationPanel.Left := WizardForm.YesRadio.Left;
  930. DonationPanel.Width := WizardForm.YesRadio.Width;
  931. DonationPanel.Parent := WizardForm.FinishedPage;
  932. DonationPanel.Top := ScaleY(190);
  933. DonationPanel.Height := ScaleY(110);
  934. DonationPanel.BevelInner := bvNone;
  935. DonationPanel.BevelOuter := bvNone;
  936. DonationPanel.Color := WizardForm.FinishedPage.Color;
  937. Caption := TLabel.Create(DonationPanel);
  938. Caption.Left := 0;
  939. Caption.Top := 0;
  940. Caption.Width := DonationPanel.Width;
  941. Caption.Parent := DonationPanel;
  942. Caption.Caption := ExpandConstant('{cm:PleaseDonate}');
  943. P := Caption.Top + Caption.Height + ScaleY(12);
  944. CreateDonateLink( 9, 0, P);
  945. CreateDonateLink(19, 1, P);
  946. CreateDonateLink(29, 2, P);
  947. CreateDonateLink(49, 3, P);
  948. Caption := TLabel.Create(DonationPanel);
  949. Caption.Left := 0;
  950. Caption.Top := P + 3 * ScaleY(16) + ScaleY(24);
  951. Caption.Parent := DonationPanel;
  952. Caption.Caption := ExpandConstant('{cm:AboutDonations}');
  953. Caption.OnClick := @AboutDonationsLinkClick;
  954. LinkLabel(Caption);
  955. PayPalCardImagePath := ExpandConstant('{tmp}\{#PayPalCardImage}');
  956. ExtractTemporaryFile(ExtractFileName(PayPalCardImagePath));
  957. PayPalCardImage := TBitmapImage.Create(DonationPanel);
  958. PayPalCardImage.AutoSize := True;
  959. PayPalCardImage.Bitmap.LoadFromFile(PayPalCardImagePath);
  960. PayPalCardImage.Cursor := crHand;
  961. PayPalCardImage.Parent := DonationPanel;
  962. PayPalCardImage.Left := ScaleX(100);
  963. PayPalCardImage.Top := P + ScaleX(8);
  964. PayPalCardImage.ReplaceColor := $FCFE04;
  965. PayPalCardImage.ReplaceWithColor := WizardForm.FinishedPage.Color;
  966. PayPalCardImage.Hint := ExpandConstant('{cm:AboutDonations}');
  967. PayPalCardImage.ShowHint := True;
  968. PayPalCardImage.OnClick := @AboutDonationsLinkClick;
  969. #endif
  970. WizardForm.YesRadio.OnClick := @UpdatePostInstallRunCheckboxes;
  971. WizardForm.NoRadio.OnClick := @UpdatePostInstallRunCheckboxes;
  972. UpdatePostInstallRunCheckboxes(nil);
  973. if IsWin8 then
  974. begin
  975. WizardForm.NoIconsCheck.Checked := True;
  976. end;
  977. #ifdef OpenCandy
  978. OpenCandyInit('{#OC_STR_MY_PRODUCT_NAME}', '{#OC_STR_KEY}', '{#OC_STR_SECRET}',
  979. ExpandConstant('{cm:LanguageISOCode}'), {#OC_INIT_MODE_NORMAL});
  980. OpenCandyNewPageID := OpenCandyInsertLoadDLLPage(wpLicense);
  981. OpenCandyInsertConnectPage(OpenCandyNewPageID);
  982. OpenCandyNewPageID := OpenCandyInsertLoadingPage(wpSelectTasks, ' ', ' ', 'Loading...', 'Arial', 100);
  983. OpenCandyInsertOfferPage(OpenCandyNewPageID);
  984. #endif
  985. #ifdef Chrome
  986. ExtractTemporaryFile('{#ChromeGcApiDllFile}');
  987. ExtractTemporaryFile('{#ChromeCheckerFile}');
  988. ChromeAllowed :=
  989. (not WizardSilent) and
  990. ExecAsOriginalUser(ExpandConstant('{tmp}\{#ChromeCheckerFile}'), 'checkstandard', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
  991. (ResultCode = 0) and
  992. Exec(ExpandConstant('{tmp}\{#ChromeCheckerFile}'), 'checkelevated', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
  993. (ResultCode = 0);
  994. if ChromeAllowed then
  995. begin
  996. Log('Chrome allowed');
  997. ChromePage := CreateCustomPage(wpInterface,
  998. ExpandConstant('{cm:ChromeTitle}'),
  999. ExpandConstant('{cm:ChromePrompt}'));
  1000. Caption := TLabel.Create(ChromePage);
  1001. Caption.WordWrap := True;
  1002. Caption.Caption :=
  1003. '- ' + ExpandConstant('{cm:ChromePoint1}') + #13#10 +
  1004. '- ' + ExpandConstant('{cm:ChromePoint2}') + #13#10 +
  1005. '- ' + ExpandConstant('{cm:ChromePoint3}');
  1006. Caption.Width := ChromePage.SurfaceWidth;
  1007. Caption.Parent := ChromePage.Surface;
  1008. ChromeAdImage := TBitmapImage.Create(ChromePage);
  1009. ChromeAdImage.Top := Caption.Top + Caption.Height + ScaleY(6);
  1010. ChromeAdImage.Parent := ChromePage.Surface;
  1011. LoadEmbededBitmap(ChromeAdImage, '{#ChromeAdFile}');
  1012. ChromeCheckbox := TCheckbox.Create(ChromePage);
  1013. ChromeCheckbox.Top := ChromeAdImage.Top + ChromeAdImage.Height + ScaleY(6);
  1014. ChromeCheckbox.Left := ScaleX(4);
  1015. ChromeCheckbox.Width :=
  1016. ChromePage.SurfaceWidth - ChromeCheckbox.Left;
  1017. ChromeCheckbox.Caption := ExpandConstant('{cm:ChromeCheck}');
  1018. ChromeCheckbox.Checked := True;
  1019. ChromeCheckbox.Parent := ChromePage.Surface;
  1020. ChromeCheckbox.OnClick := @ChromeCheckboxClick;
  1021. ChromeDefaultCheckbox := TCheckbox.Create(ChromePage);
  1022. ChromeDefaultCheckbox.Top :=
  1023. ChromeCheckbox.Top + ChromeCheckbox.Height + ScaleY(4);
  1024. ChromeDefaultCheckbox.Left := ScaleX(4);
  1025. ChromeDefaultCheckbox.Width :=
  1026. ChromePage.SurfaceWidth - ChromeDefaultCheckbox.Left;
  1027. ChromeDefaultCheckbox.Caption := ExpandConstant('{cm:ChromeDefaultCheck}');
  1028. ChromeDefaultCheckbox.Checked := True;
  1029. ChromeDefaultCheckbox.Parent := ChromePage.Surface;
  1030. ChromeLastPolicyText := nil;
  1031. AddChromePolicyText('{cm:ChromeDisclaimerPrefix}', nil);
  1032. AddChromePolicyText('{cm:ChromeDisclaimerTermsOfUse}', @ChromeTermsOfUseClick);
  1033. AddChromePolicyText('{cm:ChromeDisclaimerInfix}', nil);
  1034. AddChromePolicyText('{cm:ChromeDisclaimerPrivacyPolicy}', @ChromePrivacyPolicyClick);
  1035. AddChromePolicyText('{cm:ChromeDisclaimerPostfix}', nil);
  1036. // override the windows scheme to make sure it matches chrome logo background
  1037. WizardForm.MainPanel.Color := clWhite;
  1038. ChromeLogoImage := TBitmapImage.Create(WizardForm.MainPanel);
  1039. ChromeLogoImage.Top := WizardForm.PageNameLabel.Top;
  1040. ChromeLogoImage.Left := ScaleX(8);
  1041. ChromeLogoImage.Parent := WizardForm.MainPanel;
  1042. LoadEmbededBitmap(ChromeLogoImage, '{#ChromeLogoFile}');
  1043. ChromeLogoImage.Visible := False;
  1044. ChromeLogoImageOffset :=
  1045. (ChromeLogoImage.Left + ChromeLogoImage.Width + ScaleX(8)) -
  1046. WizardForm.PageNameLabel.Left;
  1047. end;
  1048. #endif
  1049. end;
  1050. procedure RegisterPreviousData(PreviousDataKey: Integer);
  1051. var
  1052. S: string;
  1053. begin
  1054. if TypicalTypeButton.Checked then S := 'typical'
  1055. else S := 'custom';
  1056. SetPreviousData(PreviousDataKey, '{#SetupTypeData}', S);
  1057. end;
  1058. procedure CurPageChanged(CurPageID: Integer);
  1059. var
  1060. Delta: Integer;
  1061. LineHeight: Integer;
  1062. LaunchCheckboxTop: Integer;
  1063. begin
  1064. #ifdef OpenCandy
  1065. OpenCandyCurPageChanged(CurPageID);
  1066. #endif
  1067. if CurPageID = wpInterface then
  1068. begin
  1069. AdditionalOptionsCaption.Visible := not TypicalTypeButton.Checked;
  1070. AdvancedTabsCheckbox.Visible := not TypicalTypeButton.Checked;
  1071. end
  1072. else
  1073. if CurPageID = wpFinished then
  1074. begin
  1075. LineHeight := (WizardForm.NoRadio.Top - WizardForm.YesRadio.Top);
  1076. // Are we at the "Restart?" screen
  1077. if WizardForm.YesRadio.Visible then
  1078. begin
  1079. WizardForm.FinishedLabel.Caption :=
  1080. ExpandConstant('{cm:FinishedRestartDragExtLabel}') + NewLine;
  1081. Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
  1082. WizardForm.YesRadio.Top := WizardForm.YesRadio.Top + Delta;
  1083. WizardForm.NoRadio.Top := WizardForm.NoRadio.Top + Delta;
  1084. LaunchCheckboxTop := WizardForm.NoRadio.Top + LineHeight;
  1085. #ifdef Donations
  1086. DonationPanel.Visible := False;
  1087. #endif
  1088. end
  1089. else
  1090. begin
  1091. LaunchCheckboxTop := WizardForm.RunList.Top;
  1092. #ifdef Donations
  1093. DonationPanel.Visible := not IsChromeSelected;
  1094. #endif
  1095. end;
  1096. LaunchCheckbox.Top := LaunchCheckboxTop;
  1097. OpenGettingStartedCheckbox.Top := LaunchCheckbox.Top + LineHeight;
  1098. LaunchChromeCheckbox.Visible := IsChromeSelected;
  1099. LaunchChromeCheckbox.Top := OpenGettingStartedCheckbox.Top + LineHeight;
  1100. UpdatePostInstallRunCheckboxes(nil);
  1101. end;
  1102. if CurPageID = wpSetupType then
  1103. begin
  1104. Log('License accepted');
  1105. LicenseAccepted := True;
  1106. end;
  1107. #ifdef Chrome
  1108. if ChromeAllowed then
  1109. begin
  1110. if CurPageID = wpChrome then
  1111. begin
  1112. WizardForm.PageNameLabel.Width := WizardForm.PageNameLabel.Width - ChromeLogoImageOffset;
  1113. WizardForm.PageNameLabel.Left := WizardForm.PageNameLabel.Left + ChromeLogoImageOffset;
  1114. WizardForm.PageDescriptionLabel.Width := WizardForm.PageDescriptionLabel.Width - ChromeLogoImageOffset;
  1115. WizardForm.PageDescriptionLabel.Left := WizardForm.PageDescriptionLabel.Left + ChromeLogoImageOffset;
  1116. ChromeLogoImage.Visible := True;
  1117. end
  1118. else
  1119. if ChromeLogoImage.Visible then
  1120. begin
  1121. ChromeLogoImage.Visible := False;
  1122. WizardForm.PageNameLabel.Left := WizardForm.PageNameLabel.Left - ChromeLogoImageOffset;
  1123. WizardForm.PageNameLabel.Width := WizardForm.PageNameLabel.Width + ChromeLogoImageOffset;
  1124. WizardForm.PageDescriptionLabel.Left := WizardForm.PageDescriptionLabel.Left - ChromeLogoImageOffset;
  1125. WizardForm.PageDescriptionLabel.Width := WizardForm.PageDescriptionLabel.Width + ChromeLogoImageOffset;
  1126. end;
  1127. end;
  1128. #endif
  1129. end;
  1130. #ifdef OpenCandy
  1131. function BackButtonClick(CurPageID: Integer): Boolean;
  1132. begin
  1133. Result := True;
  1134. OpenCandyBackButtonClick(CurPageID);
  1135. end;
  1136. function NextButtonClick(CurPageID: Integer): Boolean;
  1137. begin
  1138. Result := OpenCandyNextButtonClick(CurPageID);
  1139. end;
  1140. #endif
  1141. function AskedRestart: Boolean;
  1142. begin
  1143. Result := WizardForm.YesRadio.Visible;
  1144. end;
  1145. procedure DeinitializeSetup;
  1146. var
  1147. WinHttpReq: Variant;
  1148. ReportUrl: string;
  1149. ReportData: string;
  1150. begin
  1151. #ifdef OpenCandy
  1152. OpenCandyDeinitializeSetup();
  1153. #endif
  1154. // cannot send report, unless user already accepted license
  1155. // (with privacy policy)
  1156. if LicenseAccepted then
  1157. begin
  1158. Log('Preparing intallation report');
  1159. ReportData := Format(
  1160. 'installed=%d&silent=%d&ver=%s&lang=%s&', [
  1161. Integer(InstallationDone), Integer(WizardSilent),
  1162. ExpandConstant('{#VersionOnly}'), ActiveLanguage]);
  1163. #ifdef Chrome
  1164. ReportData := ReportData +
  1165. Format('chromeoffered=%d&chromeaccepted=%d&chromelaunched=%d&', [Integer(ChromeAllowed), Integer(IsChromeSelected), Integer(ChromeLaunched)]);
  1166. #endif
  1167. try
  1168. ReportUrl := ExpandConstant('{#WebReport}?') + ReportData;
  1169. Log('Sending installation report: ' + ReportUrl);
  1170. WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
  1171. WinHttpReq.Open('GET', ReportUrl, False);
  1172. WinHttpReq.Send('');
  1173. Log('Installation report send result: ' + IntToStr(WinHttpReq.Status) + ' ' + WinHttpReq.StatusText);
  1174. except
  1175. Log('Error sending installation report: ' + GetExceptionMessage);
  1176. end;
  1177. end;
  1178. end;
  1179. procedure CurStepChanged(CurStep: TSetupStep);
  1180. var
  1181. ErrorCode: Integer;
  1182. ShowCmd: Integer;
  1183. Path: string;
  1184. WebGettingStarted: string;
  1185. OpenGettingStarted: Boolean;
  1186. LaunchChrome: Boolean;
  1187. begin
  1188. if CurStep = ssPostInstall then
  1189. begin
  1190. if Length(MissingTranslations) > 0 then
  1191. begin
  1192. Log('Removing obsolete translations');
  1193. WizardForm.StatusLabel.Caption :=
  1194. ExpandConstant('{cm:RemovingObsoleteTranslations}');
  1195. ProcessMissingTranslations(@DeleteTranslation);
  1196. end;
  1197. end
  1198. else
  1199. if CurStep = ssDone then
  1200. begin
  1201. if (not WizardSilent) and (not WillRestart) then
  1202. begin
  1203. OpenGettingStarted :=
  1204. OpenGettingStartedCheckbox.Enabled and
  1205. OpenGettingStartedCheckbox.Checked;
  1206. LaunchChrome :=
  1207. ChromeAllowed and IsChromeSelected and
  1208. LaunchChromeCheckbox.Visible and // sanity check
  1209. LaunchChromeCheckbox.Checked;
  1210. if OpenGettingStarted then
  1211. begin
  1212. WebGettingStarted :=
  1213. ExpandConstant('{#WebGettingStarted}') + PrevVersion;
  1214. Log('Opening getting started page: ' + WebGettingStarted);
  1215. OpenBrowser(WebGettingStarted);
  1216. end;
  1217. if LaunchCheckbox.Checked then
  1218. begin
  1219. if OpenGettingStarted or LaunchChrome then
  1220. begin
  1221. Log('Will launch WinSCP minimized');
  1222. ShowCmd := SW_SHOWMINIMIZED
  1223. end
  1224. else
  1225. begin
  1226. ShowCmd := SW_SHOWNORMAL;
  1227. end;
  1228. Log('Launching WinSCP');
  1229. Path := ExpandConstant('{app}\{#MainFileName}');
  1230. ExecAsOriginalUser(Path, '', '', ShowCmd, ewNoWait, ErrorCode)
  1231. end;
  1232. if LaunchChrome then
  1233. begin
  1234. Log('Launching Chrome');
  1235. ChromeLaunched :=
  1236. ExecAsOriginalUser(ExpandConstant('{tmp}\{#ChromeCheckerFile}'), 'launch', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode) and
  1237. (ErrorCode = 0);
  1238. Log(Format('Launched Chrome [%d] [%d]', [Integer(ChromeLaunched), ErrorCode]));
  1239. if not ChromeLaunched then
  1240. begin
  1241. MsgBox(ExpandConstant('{cm:ChromeInstallationFailed}'), mbError, MB_OK);
  1242. end;
  1243. end;
  1244. end;
  1245. end;
  1246. #ifdef OpenCandy
  1247. OpenCandyCurStepChanged(CurStep);
  1248. #endif
  1249. if CurStep = ssDone then
  1250. begin
  1251. Log('Installation done');
  1252. InstallationDone := True;
  1253. end;
  1254. end;
  1255. function ShouldSkipPage(PageID: Integer): Boolean;
  1256. begin
  1257. Result :=
  1258. #ifdef OpenCandy
  1259. OpenCandyShouldSkipPage(PageID) or
  1260. #endif
  1261. { Hide most pages during typical installation }
  1262. (TypicalTypeButton.Checked and
  1263. ((PageID = wpSelectDir) or (PageID = wpSelectComponents) or
  1264. (PageID = wpSelectProgramGroup) or (PageID = wpSelectTasks) or
  1265. { Hide Interface page for upgrades only, show for fresh installs }
  1266. ((PageID = wpInterface) and Upgrade))) or
  1267. (IsWin8 and (PageID = wpSelectProgramGroup));
  1268. end;
  1269. function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo,
  1270. MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: string): string;
  1271. var
  1272. S: string;
  1273. S2: string;
  1274. begin
  1275. S := '';
  1276. S := S + MemoDirInfo + NewLine + NewLine;
  1277. if not Upgrade then
  1278. begin
  1279. if TypicalTypeButton.Checked then S2 := ExpandConstant('{cm:TypicalType}')
  1280. else S2 := ExpandConstant('{cm:CustomType}');
  1281. end
  1282. else
  1283. begin
  1284. if TypicalTypeButton.Checked then S2 := ExpandConstant('{cm:TypicalUpgradeType}')
  1285. else S2 := ExpandConstant('{cm:CustomUpgradeType}');
  1286. end;
  1287. StringChange(S2, '&', '');
  1288. S := S + SetupMessage(msgReadyMemoType) + NewLine + Space + S2 + NewLine + NewLine;
  1289. S := S + MemoComponentsInfo + NewLine + NewLine;
  1290. if Length(MemoGroupInfo) > 0 then
  1291. S := S + MemoGroupInfo + NewLine + NewLine;
  1292. if Length(MemoTasksInfo) > 0 then
  1293. S := S + MemoTasksInfo + NewLine + NewLine;
  1294. S := S + ExpandConstant('{cm:UserSettingsOverview}') + NewLine;
  1295. S := S + Space;
  1296. if CommanderRadioButton.Checked then S2 := ExpandConstant('{cm:NortonCommanderInterfaceB}')
  1297. else S2 := ExpandConstant('{cm:ExplorerInterfaceB}');
  1298. StringChange(S2, '&', '');
  1299. S := S + S2;
  1300. S := S + NewLine;
  1301. if AdvancedTabsCheckbox.Checked then
  1302. begin
  1303. S2 := ExpandConstant('{cm:AdvancedLoginOptions}');
  1304. StringChange(S2, '&', '');
  1305. S := S + Space + S2 + NewLine;
  1306. end;
  1307. Result := S;
  1308. end;
  1309. function InitializeUninstall: Boolean;
  1310. begin
  1311. // let application know that we are running silent uninstall,
  1312. // this turns UninstallCleanup to noop
  1313. if UninstallSilent then
  1314. CreateMutex('WinSCPSilentUninstall');
  1315. Result := True;
  1316. end;