import { relative, resolve, win32 } from 'path'; import { readdirAsync, lstatAsync } from 'fs-extra-promise'; import { fixWindowsVersion } from '../util'; export interface INsisComposerOptions { // Basic. appName: string; companyName: string; description: string; version: string; copyright: string; // Compression. compression: 'zlib' | 'bzip2' | 'lzma'; solid: boolean; languages: string[]; // Output. output: string; } export class NsisComposer { public static DIVIDER = '################################################################################'; protected fixedVersion: string; constructor(protected options: INsisComposerOptions) { if(!this.options.appName) { this.options.appName = 'NO_APPNAME'; } if(!this.options.companyName) { this.options.companyName = 'NO_COMPANYNAME'; } if(!this.options.description) { this.options.description = 'NO_DESCRIPTION'; } if(!this.options.version) { this.options.version = 'NO_VERSION'; } if(!this.options.copyright) { this.options.copyright = 'NO_COPYRIGHT'; } this.options.compression = this.options.compression || 'lzma'; this.options.solid = this.options.solid ? true : false; this.options.languages = this.options.languages && this.options.languages.length > 0 ? this.options.languages : [ 'English' ]; this.fixedVersion = fixWindowsVersion(this.options.version); } public async make(): Promise { return `${ NsisComposer.DIVIDER } # # Generated by nsis-gen. # ${ NsisComposer.DIVIDER } ${ await this.makeGeneralSection() } ${ await this.makeResourcesSection() } ${ await this.makeInstallSection() } ${ await this.makeUninstallSection() } `; } protected async makeGeneralSection(): Promise { return `${ NsisComposer.DIVIDER } # # General # ${ NsisComposer.DIVIDER } !include "MUI2.nsh" Name "${ this.options.appName }" Caption "${ this.options.appName }" BrandingText "${ this.options.appName }" SetCompressor ${ this.options.solid ? '/SOLID' : '' } ${ this.options.compression } OutFile "${ win32.normalize(resolve(this.options.output)) }" InstallDir "$LOCALAPPDATA\\${ this.options.appName }" InstallDirRegKey HKCU "Software\\${ this.options.appName }" "InstallDir" RequestExecutionLevel user XPStyle on !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\\${ this.options.appName }" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "StartMenuFolder" !define MUI_FINISHPAGE_RUN "$INSTDIR\\${ this.options.appName }.exe" Var StartMenuFolder !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH ${ this.options.languages.map((language) => { return `!insertmacro MUI_LANGUAGE "${ language }"`; }).join('\n') } ${ this.options.languages.length > 1 ? `!insertmacro MUI_RESERVEFILE_LANGDLL` : '' } Function .onInit ${ this.options.languages.length > 1 ? `!insertmacro MUI_LANGDLL_DISPLAY` : '' } FunctionEnd `; } protected async makeResourcesSection(): Promise { return `${ NsisComposer.DIVIDER } # # Resources # ${ NsisComposer.DIVIDER } VIProductVersion "${ this.fixedVersion }" VIAddVersionKey "ProductName" "${ this.options.appName }" VIAddVersionKey "CompanyName" "${ this.options.companyName }" VIAddVersionKey "FileDescription" "${ this.options.description }" VIAddVersionKey "FileVersion" "${ this.fixedVersion }" VIAddVersionKey "LegalCopyright" "${ this.options.copyright }" `; } protected async makeInstallSection(): Promise { return `${ NsisComposer.DIVIDER } # # Main # ${ NsisComposer.DIVIDER } Section -Install SetShellVarContext current SetOverwrite ifnewer WriteRegStr HKCU "Software\\${ this.options.appName }" "InstallDir" "$INSTDIR" ${ await this.makeInstallerFiles() } !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\\$StartMenuFolder" CreateShortcut "$SMPROGRAMS\\$StartMenuFolder\\${ this.options.appName }.lnk" "$INSTDIR\\${ this.options.appName }.exe" CreateShortcut "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" "$INSTDIR\\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END WriteUninstaller "$INSTDIR\\Uninstall.exe" SectionEnd `; } protected async makeUninstallSection(): Promise { return `${ NsisComposer.DIVIDER } # # Uninstall # ${ NsisComposer.DIVIDER } Section Uninstall RMDir /r "$INSTDIR\\*.*" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder Delete "$SMPROGRAMS\\$StartMenuFolder\\${ this.options.appName }.lnk" Delete "$SMPROGRAMS\\$StartMenuFolder\\Uninstall.lnk" RMDir "$SMPROGRAMS\\$StartMenuFolder" DeleteRegKey HKCU "Software\\${ this.options.appName }" SectionEnd `; } protected async makeInstallerFiles(): Promise { return `SetOutPath "$INSTDIR" FILE /r .\\*.*`; } }