NsisComposer.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { relative, resolve, win32 } from 'path';
  2. import { readdirAsync, lstatAsync } from 'fs-extra-promise';
  3. import { fixWindowsVersion } from '../util';
  4. export interface INsisComposerOptions {
  5. // Basic.
  6. appName: string;
  7. companyName: string;
  8. description: string;
  9. version: string;
  10. copyright: string;
  11. // Compression.
  12. compression: 'zlib' | 'bzip2' | 'lzma';
  13. solid: boolean;
  14. languages: string[];
  15. // Output.
  16. output: string;
  17. }
  18. export class NsisComposer {
  19. public static DIVIDER = '################################################################################';
  20. protected fixedVersion: string;
  21. constructor(protected options: INsisComposerOptions) {
  22. if(!this.options.appName) {
  23. this.options.appName = 'NO_APPNAME';
  24. }
  25. if(!this.options.companyName) {
  26. this.options.companyName = 'NO_COMPANYNAME';
  27. }
  28. if(!this.options.description) {
  29. this.options.description = 'NO_DESCRIPTION';
  30. }
  31. if(!this.options.version) {
  32. this.options.version = 'NO_VERSION';
  33. }
  34. if(!this.options.copyright) {
  35. this.options.copyright = 'NO_COPYRIGHT';
  36. }
  37. this.options.compression = this.options.compression || 'lzma';
  38. this.options.solid = this.options.solid ? true : false;
  39. this.options.languages = this.options.languages && this.options.languages.length > 0 ? this.options.languages : [ 'English' ];
  40. this.fixedVersion = fixWindowsVersion(this.options.version);
  41. }
  42. public async make(): Promise<string> {
  43. return `${ NsisComposer.DIVIDER }
  44. #
  45. # Generated by nsis-gen.
  46. #
  47. ${ NsisComposer.DIVIDER }
  48. ${ await this.makeGeneralSection() }
  49. ${ await this.makeResourcesSection() }
  50. ${ await this.makeInstallSection() }
  51. ${ await this.makeUninstallSection() }
  52. `;
  53. }
  54. protected async makeGeneralSection(): Promise<string> {
  55. return `${ NsisComposer.DIVIDER }
  56. #
  57. # General
  58. #
  59. ${ NsisComposer.DIVIDER }
  60. !include "MUI2.nsh"
  61. Name "${ this.options.appName }"
  62. Caption "${ this.options.appName }"
  63. BrandingText "${ this.options.appName }"
  64. SetCompressor ${ this.options.solid ? '/SOLID' : '' } ${ this.options.compression }
  65. OutFile "${ win32.normalize(resolve(this.options.output)) }"
  66. InstallDir "$LOCALAPPDATA\\${ this.options.appName }"
  67. InstallDirRegKey HKCU "Software\\${ this.options.appName }" "InstallDir"
  68. RequestExecutionLevel user
  69. XPStyle on
  70. !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
  71. !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\\${ this.options.appName }"
  72. !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "StartMenuFolder"
  73. !define MUI_FINISHPAGE_RUN "$INSTDIR\\${ this.options.appName }.exe"
  74. Var StartMenuFolder
  75. !insertmacro MUI_PAGE_WELCOME
  76. !insertmacro MUI_PAGE_DIRECTORY
  77. !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
  78. !insertmacro MUI_PAGE_INSTFILES
  79. !insertmacro MUI_PAGE_FINISH
  80. !insertmacro MUI_UNPAGE_WELCOME
  81. !insertmacro MUI_UNPAGE_CONFIRM
  82. !insertmacro MUI_UNPAGE_INSTFILES
  83. !insertmacro MUI_UNPAGE_FINISH
  84. ${
  85. this.options.languages.map((language) => {
  86. return `!insertmacro MUI_LANGUAGE "${ language }"`;
  87. }).join('\n')
  88. }
  89. ${
  90. this.options.languages.length > 1
  91. ? `!insertmacro MUI_RESERVEFILE_LANGDLL`
  92. : ''
  93. }
  94. Function .onInit
  95. ${
  96. this.options.languages.length > 1
  97. ? `!insertmacro MUI_LANGDLL_DISPLAY`
  98. : ''
  99. }
  100. FunctionEnd
  101. `;
  102. }
  103. protected async makeResourcesSection(): Promise<string> {
  104. return `${ NsisComposer.DIVIDER }
  105. #
  106. # Resources
  107. #
  108. ${ NsisComposer.DIVIDER }
  109. VIProductVersion "${ this.fixedVersion }"
  110. VIAddVersionKey "ProductName" "${ this.options.appName }"
  111. VIAddVersionKey "CompanyName" "${ this.options.companyName }"
  112. VIAddVersionKey "FileDescription" "${ this.options.description }"
  113. VIAddVersionKey "FileVersion" "${ this.fixedVersion }"
  114. VIAddVersionKey "LegalCopyright" "${ this.options.copyright }"
  115. `;
  116. }
  117. protected async makeInstallSection(): Promise<string> {
  118. return `${ NsisComposer.DIVIDER }
  119. #
  120. # Main
  121. #
  122. ${ NsisComposer.DIVIDER }
  123. Section -Install
  124. SetShellVarContext current
  125. SetOverwrite ifnewer
  126. WriteRegStr HKCU "Software\\${ this.options.appName }" "InstallDir" "$INSTDIR"
  127. ${ await this.makeInstallerFiles() }
  128. !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
  129. CreateDirectory "$SMPROGRAMS\\$StartMenuFolder"
  130. CreateShortcut "$SMPROGRAMS\\$StartMenuFolder\\${ this.options.appName }.lnk" "$INSTDIR\\${ this.options.appName }.exe"
  131. CreateShortcut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe"
  132. !insertmacro MUI_STARTMENU_WRITE_END
  133. WriteUninstaller "$INSTDIR\\Uninstall.exe"
  134. SectionEnd
  135. `;
  136. }
  137. protected async makeUninstallSection(): Promise<string> {
  138. return `${ NsisComposer.DIVIDER }
  139. #
  140. # Uninstall
  141. #
  142. ${ NsisComposer.DIVIDER }
  143. Section Uninstall
  144. RMDir /r "$INSTDIR\\*.*"
  145. RMDir "$INSTDIR"
  146. !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
  147. Delete "$SMPROGRAMS\\$StartMenuFolder\\${ this.options.appName }.lnk"
  148. Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk"
  149. RMDir "$SMPROGRAMS\\$StartMenuFolder"
  150. DeleteRegKey HKCU "Software\\${ this.options.appName }"
  151. SectionEnd
  152. `;
  153. }
  154. protected async makeInstallerFiles(): Promise<string> {
  155. return `SetOutPath "$INSTDIR"
  156. FILE /r .\\*.*`;
  157. }
  158. }