Add NSIS script with electron builder to run DPInst.exe during install - nsis

I'm using electron-builder to create NSIS Windows installers for my electron app. During install I need to run the included DPInst.exe to make sure drivers get installed.
I can tell electron-builder than I'm including a custom script:
"nsis": {
"include": "build/installer.nsh"
}
But I can't work out what should be in the installer.nsh
The docs say that I need something like:
!macro customInstall
!system "echo '' > ${BUILD_RESOURCES_DIR}/customInstall"
!macroend
And I've seen some NSIS commands to run DPInst.exe
ExecWait '"$INSTDIR\resources\DPInst.exe" /sw'
But I'm unsure how to combine them as I can't work out the syntax!

Well, it was pretty obvious 🤦‍♂️. I just had to combine the two:
!macro customInstall
ExecWait '"$INSTDIR\resources\DPInst.exe" /sw'
!macroend

For me, ExecWait '"$INSTDIR\resources\DPInst.exe" /sw' alone wasn't working because of permission issues.
I had to add RequestExecutionLevel admin
installer.nsh looks like -
!macro customHeader
RequestExecutionLevel admin
!macroend
!macro customInstall
ExecWait '"$INSTDIR\ABC_Setup.exe" /sw'
!macroend

Related

Electron-builder NSIS, embedding other installers

I have created a little electron program for one of my friends, it is a patcher for a private metin2 server of some sort. The game itself is really old so it requires a few redisturables to be installed.
[dxwebsetup0411 / dotNetFx35setup / vcredist_x86 ( i believe its a 2013 version) ]
I want to include them as an option at the end of the install (or even before it, doesn't really matter).
I have found a few examples how to do so but they are all for Standalone NSIS installers and when i try to include that script ( in the build/installer.nsh file ), the build process crashes, presumably because its not the main build script therefor adding Sections is prohibited (?).
Im really new to NSIS scripts and NSIS overall.
So far i only figured out how to put checkboxes and labels and so on in, with the help of nsDialogs, but as i looked at its documentation, it seemed that there are no option where i could do this.
Any help would be greatly appreciated.
EDIT :
My script currently is almost empty, I only changed the default directory, but anyway here is that:
!macro preInit
SetRegView 64
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Decay2"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Decay2"
SetRegView 32
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Decay2"
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "C:\Decay2"
!macroend
Everything i know about electron-builder's NSIS main script and this included script is here :
Custom Script Example
NSIS- Electron Builder
It is definitely possible to embed other installers and execute them. See this example on SO:
Embedding other installers using NSIS
or these official NSIS tutorials/guides: https://nsis.sourceforge.io/Embedding_other_installers
Please post your script and build file(s) if you have some issue with your script and you expect specific answer.

NSIS uninstaller doesn't run un.onInit

In my .nsi file I have the following logic in the un.onInit function:
Function un.onInit
MessageBox MB_YESNO "This will uninstall. Continue?" IDYES checkRunning
checkRunning:
FindProcDLL::FindProc "app.exe"
IntCmp $R0 1 0 notRunning
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "${PRODUCT} is running, please close it so the installation can proceed." /SD IDCANCEL IDRETRY checkRunning
Abort
notRunning:
!insertmacro Init "uninstaller"
FunctionEnd
However, the messageBox (and the process is running message) is never shown. So I went through a lot of documentation and apparently running silent mode prevents this method being called so I added SilentInstall normal and SilentUnInstall normal to the .nsi file. However, this doesn't work either.
I tried invoking the uninstaller by manually going to the uninstall.exe and by running the installer which checks if there is already a version installed and if there is calling:
uninst:
ClearErrors
ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" "UninstallString"
StrCmp $R0 "" done
Abort
Yet both of these invokes do not trigger to 'normal' mode. So how can I get my un.onInit function to be called?
Edit:
As someone asked for the whole file, here it is. I copied the relevant parts only, but if more is needed feel free to check it out. Note that the whole file is already quite old, I am merely updating it.
After upgrading the MUI2 (Modern User Interface 2.0), downgrading to NSIS 2.5 and using the NsProcess plug-in, I got it working. The function is now being called and my check works using the new plugin. The FindProcDLL plugin is broken on NSIS > 2.46

Installing Fonts using NSIS

I am installing fonts in my setup application using:
Section "Fonts"
SetOutPath "$FONTS"
StrCpy $FONT_DIR $FONTS
!insertmacro InstallTTFfont '..\FONTS\English\Arial.ttf'
SendMessage ${HWND_BROADCAST} ${WM_FONTCHANGE} 0 0 /TIMEOUT=5000
SectionEnd
(I have included !include FontReg.nsh and !include FontName.nsh)
At times, especially on Win 7(with UAC enabled), the setup progress goes into a non-reponsive mode(progress bar remains frozen at the end of the font installation and setup does not proceed). Is there anything to avoid this scenario?. Kindly help.
Thanks,
Bomzinho
There is some macros dedicated for registering fonts available on the NSIS wiki. They do a bit more than just copying the .ttf file.
Also you could look at the page on http://nsis.sourceforge.net/Advanced_Font_Installation

NSIS doesn't abort install when uninstall is in onInit

I have an installer that makes it mandatory to uninstall the previous version before the new version can be installed.
However, when the initial question gets asked it does so. But the uninstall dialogue doesn't.
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
"${PRODUCT_NAME} is already installed. $\n$\nIf you have software older than 3.0, please manually uninstall it with Windows before procedeing. $\n$\nClick `OK` to remove the \
previous version or `Cancel` to cancel this upgrade." \
IDOK uninst IDCANCEL giveup
; I am giving up
giveup:
Abort
; Run the uninstaller
uninst:
ClearErrors
ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
IfErrors no_remove_uninstaller
no_remove_uninstaller:
install:
; ..... snip
Then here
Function un.onInit
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES NoAbort
Abort
NoAbort:
FunctionEnd
So, when it is a standalone uninstall it seems to be fine, but when it is uninstalling at the beginning, if a user says No/Cancel, the installer will still go on when they say no. I can't think of a reason as to why. As an ill side-effect, the program files icon on start menu is orphaned and the uninst.exe is orphaned. But if you run the uninstaller "manually" it seems to be fine. I had no changed any of that logic other than trying to get this thing to work.
Thanks.
It is important to quote the path in ExecWait and then check the exit code:
Function .onInit
StrCpy $R0 "c:\old install" ; TODO: Somehow find the old install (in the registry? InstallDirRegKey?) and put its path in $R0
IfFileExists "$R0\*.*" 0 noOldInstall
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT_NAME} is already installed. blahblah..." IDOK uninstOld
Abort
uninstOld:
ExecWait '"$R0\uninstaller.exe" _?=$R0' $R1
; Exit codes are documented in Appendix D in the help file.
StrCmp $R1 0 noOldInstall ; Success? If so we are done...
Abort ; Uninstaller was canceled or failed, we cannot continue
noOldInstall:
FunctionEnd

NSIS - Silent Autoupdate Application

I have an NSIS install kit for my .net c# application.
Is there a way to silently autoupdate my application, considering that I already downloaded the new update (new NSIS app version) to local computer ?
Thanks! :)
(In case you need to detect the command line /Autoupdate=yes)
!include FileFunc.nsh
!insertmacro GetParameters
!insertmacro GetOptions
Var CMD_ARGS
Var CMD_RES
Function .onInit
#
#installer stuff.
#
StrCpy $CMD_ARGS ""
StrCpy $CMD_RES "no"
${GetParameters} $CMD_ARGS
ClearErrors
${GetOptions} $CMD_ARGS /Autoupdate= $CMD_RES
StrCmp $CMD_RES "yes" is_update is_not_update
is_update:
#Execute all your update code(run your update app, etc)
MessageBox MB_OK|MB_ICONEXCLAMATION "IS UPDATE"
goto end_auto_update_check
is_not_update:
#Execute all your non-update code.
MessageBox MB_OK|MB_ICONEXCLAMATION "IS NOT UPDATE"
end_auto_update_check:
FunctionEnd
You can run the installer silently and install on top if that is what you mean:
foo.exe /S /D=C:\Program Files\Foo
It's not necessary to pass /S to the command line if you've set up the package script to specify silent installs.
Take a look at the silent.nsi example on the NSIS site silent.nsi

Resources