Reputation: 353
I am currently using os-service to create a Windows service that needs to be packaged with my Electron application. Currently, everything is installed with NSIS, but I'm not quite sure how to install and run an os-service script during installation. Likewise for uninstallation.
Anyone with experience with this? The service is installed using node to run the script.
Upvotes: 4
Views: 1926
Reputation: 1484
There's a few things that the NSIS script installer will need to do:
Likewise for uninstalling you'll need to :
Below is the script that I use for doing all the things mentioned above and more.
;!include "MUI2.nsh"
; this script will clean the folder where the application was installed
!include "UninstallLog.nsh"
; this script is to support IF THEN
!include LogicLib.nsh
#############################################################################################
# Start
#############################################################################################
Icon "MyIcon.ico"
;miscellaneous variables
!define VERSION "1.0.0" ; app version to display on control panel
!define NAME "superapp-services-backend" ; app name to display on control panel
!define ARP "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
!define PRODUCT_PUBLISHER "dummy corp" ; app publisher to display on control panel
!define PRODUCT_URL "https://www.dummycorp.com/" ; URL to display on control panel
!define DEFAULT_DIR 'superapp-backend' ; default folder name
!define UninstId "NSISTest" ; You might want to use a GUID here
!define MIN_NODE_MAJOR 'v18' ; minimum node Major version
; application name to show on the installer
Name "superapp service Mini Backend"
;You can remove the text 'Nullsoft Install System vX.XX' from the installer window by setting the installer attribute
BrandingText "${PRODUCT_PUBLISHER}"
;define installer name
OutFile "superapp-service-be-installer-${VERSION}.exe"
; execute as admin
RequestExecutionLevel admin
Unicode True
; set C:/ProgramFiles as default install directory
InstallDir $PROGRAMFILES64\${NAME}
; Registry key to check for directory (so if you install again, it will overwrite the old one automatically)
InstallDirRegKey HKLM "Software\${NAME}" "Install_Dir"
#############################################################################################
# Sign the installers
#############################################################################################
;sign the installer
!finalize 'ssl-certificates\dummy-ssl-certificates\signtool sign /v /f ssl-certificates\dummy-ssl-certificates\signing_keys\MySPC.pfx /fd SHA256 /t http://timestamp.digicert.com "%1"' ;= 0;
;sign the uninstaller
!uninstfinalize 'ssl-certificates\dummy-ssl-certificates\signtool sign /v /f ssl-certificates\dummy-ssl-certificates\signing_keys\MySPC.pfx /fd SHA256 /t http://timestamp.digicert.com "%1"'; = 0;
#############################################################################################
# Installer Pages
#############################################################################################
Page components
Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles
#############################################################################################
### Add Prerequsites
#############################################################################################
Section "NodeJS 18" nodev18.17.1
ExecWait 'msiexec /i "Prerequisites\node-v18.17.1-x64.msi"'
SectionEnd
#############################################################################################
# default section start
#############################################################################################
Section "${NAME}-${VERSION} Backend Services" Backend
;call UserInfo plugin to get user info. The plugin puts the result in the stack
#UserInfo::GetAccountType
#Pop $0
#StrCmp $0 "Admin" +3
# MessageBox MB_OK|MB_ICONSTOP "User must have administrative privileges to install this application"
# Return
; Check if the application is already installed
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "UninstallString"
${If} $0 != ""
MessageBox MB_OK|MB_ICONEXCLAMATION "${NAME} is already installed, please uninstall the current version before proceeding"
Return
${EndIf}
; check node js version , abort if not installed or wrong version
nsExec::ExecToStack '"node" "--version"'
Pop $0
Pop $1
;node js is not installed
${If} $1 == ""
MessageBox MB_OK|MB_ICONSTOP "Node.js version ${MIN_NODE_MAJOR} was not found. Installation will be aborted"
Return
${EndIf}
; node js is installed
${If} $1 != ""
StrCpy $3 $1 3 0 ; get node js major version
${If} $3 != "${MIN_NODE_MAJOR}"
MessageBox MB_OK|MB_ICONSTOP "Found Node.js version $1Node.js ${MIN_NODE_MAJOR} is required. Installation will be aborted"
Return
${EndIf}
${EndIf}
; define output path
SetOutPath $INSTDIR
; to make this item mandatory
; SectionIn RO
; copy application signing and https certificates
File /nonfatal /a /r "ssl-certificates\"
; copy node js project files
File /nonfatal /a /r "service-mynodejs-Services\" #note back slash at the end
; register signing key with powershell into local pc certificate store
ExecWait "powershell Import-Certificate .\dummy-ssl-certificates\signing_keys\MyCA.cer -CertStoreLocation Cert:\LocalMachine\Root ; Start-Sleep -Seconds 3"
; register tls/ssl certificates with powershell into local pc certificate store
ExecWait "powershell Import-Certificate .\dummy-ssl-certificates\https-cert\ca.pem -CertStoreLocation Cert:\LocalMachine\Root ; Start-Sleep -Seconds 3"
; install npm packages
ExecWait 'cmd.exe /K npm i'
; install project as a Windows service
ExecWait 'cmd.exe /K npm install -g node-windows'
ExecWait 'cmd.exe /K node nodeService.js'
; create a file with the application version number
FileOpen $0 "$INSTDIR\version.txt" w
; write the version number to the output file
FileWrite $0 "${NAME} ${VERSION}"
; close the file
FileClose $0
;create shortcuts
;CreateShortcut "$DESKTOP\${NAME}.lnk" "$INSTDIR\uninstall.exe" "" "" ""
CreateDirectory "$SMPROGRAMS\${NAME}"
CreateShortcut "$SMPROGRAMS\${NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "" ""
;CreateShortcut "$SMPROGRAMS\${NAME}\Example2 (MakeNSISW).lnk" "$INSTDIR\example2.nsi"
; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\${NAME} "Install_Dir" "$INSTDIR"
WriteRegStr HKLM "${ARP}" "DisplayName" "${NAME} (remove only)"
WriteRegStr HKLM "${ARP}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "${ARP}" "URLInfoAbout" "${PRODUCT_URL}"
WriteRegStr HKLM "${ARP}" "DisplayVersion" "${VERSION}"
; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayName" "${NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoRepair" 1
WriteUninstaller "$INSTDIR\uninstall.exe"
; start the backend service
ExecWait "powershell Start-Service -Name mynodejsapp.exe ; Start-Sleep -Seconds 3"
;ask to reboot the pc after installing
MessageBox MB_YESNO|MB_ICONQUESTION "Setup Complete. Do you wish to reboot the system?" IDNO +2
Reboot
SectionEnd
#############################################################################################
# create a section to define what the uninstaller does. the section will always be named "Uninstall"
#############################################################################################
Section "Uninstall"
; stop and delete the backend service
ExecWait "powershell Stop-Service -Name mynodejsapp.exe ; Start-Sleep -Seconds 3 ; sc.exe delete mynodejsapp.exe ; Start-Sleep -Seconds 3 "
; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
DeleteRegKey HKLM SOFTWARE\${NAME}
; Remove shortcuts, if any
Delete "$DESKTOP\${NAME}.lnk"
; Delete installed file
Delete $INSTDIR\version.txt
; Delete the uninstaller
Delete $INSTDIR\uninstall.exe
; Remove directories and files
RMDir $SMPROGRAMS\${NAME}
!insertmacro RemoveFilesAndSubDirs "$INSTDIR"
SectionEnd
Upvotes: 0
Reputation: 5472
When you install Node.js runtime on target computer it should contain everything necessary to run apps properly.
Node.js also installs npm so it should be possible to execute npm install os-service
from your NSIS installer somehow like this:
npm install os-service
from your installer - again use ExecWait or related. You will have to use absolute paths and so on.I have no experience with web apps, there more be some dependencies and so on so you need to do a little more investigation.
Upvotes: 1