winscpsetup.iss 50 KB

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