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
Related
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
Hi i have problems with execwait. Here is some code:
SetOutPath "$INSTDIR\myDir"
ExecWait '"$INSTDIR\myDir\Myexe.exe"' $0
This fails and the error code in $0 is -1073741515
The path and the exe exist.
If i run the same setup a second time this code works fine, the exe is executed and no error code is set.
What am i doing wrong? Any idea?
It is probably a problem with Myexe.exe and not NSIS. To be sure you have to figure out if the CreateProcess call inside ExecWait failed or if this is just the exit code from the program:
!include LogicLib.nsh
Section
ClearErrors
ExecWait '"$SysDir\Charmap.exe"' $0
${If} ${Errors}
MessageBox mb_iconstop "Unable to start program!"
${Else}
MessageBox mb_ok "Program started successfully, the program exited with code $0"
${EndIf}
SectionEnd
If you get the "Program started successfully" message but the program still fails then perhaps there is something that needs to be registered for the program to work successfully and the registration is complete the next time you run it.
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
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
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