- NSIS Discussion
- Trying to check if program installed already, if so, warn
Archive: Trying to check if program installed already, if so, warn
Zethris
19th March 2007 17:13 UTC
Trying to check if program installed already, if so, warn
Function ClientCheck
IfFileExists "$INSTDIR\File Upload Service\File.exe" warn
warn:
MessageBox MB_OKCANCEL|MB_ICONSTOP "You are trying to install over an existing installation \
of the Client.$\nPlease uninstall the existing version and run the installer again by \
clicking on $\"Ok$\" or click on $\"Cancel$\" to abort this installation." \
/SD IDOK IDOK QuietUninstall IDCANCEL
Goto done
QuietUninstall:
ExecWait '"$INSTDIR\uninstall.exe" /S _=$INSTDIR'
Goto done
done:
abort
FunctionEnd
The issue I am having is that whether or not it sees the file, the warning still comes up and it seems that no matter if they click on cancel, it will continue installation when I would like for it to fully abort. Then if they click on "OK" it will uninstall, but then continue with installation right after rather than completing the uninstall and relaunching the installer or aborting the installation totally as the current message I have says to re-launch after uninstallation.
The reason for this is that the installer when on a clean install, it creates a folder and shares it on the network. Then installs a service and starts it after everything is installed.
When uninstall runs, the network shared file un-shares and is deleted, then it stops and uninstalls an installed service and it will remove the remaining files after a reboot (or, at least, the files cannot be unwritten or deleted until the service has fully stopped and uninstalled and I haven't found a way to set a time delay to wait for the service to stop yet)
So what happens now, if someone re-runs the installer again and goes to the point where it begins copying files to the install directory, it gets a file write error as the folder may be connected to by other computers on the network and the service is also still running.
Re-Running the setup is a needed ability to both easily be able to uninstall it (for the less computer literate) and also be able to modify a configuration file using the ReplaceInFile method when a user on a custom page, which has a drop down menu, makes a particular selection then passes it to the leave page that changes the environment of the installed client.
What might you recommend the approach to this might be? Am I on the right track?
I am definitely newer to using NSIS, but I have been able to get a lot out of the support system here and I thank you all for that!
Red Wine
19th March 2007 17:17 UTC
warn is the label just below the IfFileExists instruction so one way or another it goes there ;)
Zethris
19th March 2007 17:21 UTC
Function ClientCheck
IfFileExists "$INSTDIR\File Upload Service\File.exe" warn
Goto done
warn:
MessageBox MB_OKCANCEL|MB_ICONSTOP "You are trying to install over an existing installation \
of the Client.$\nPlease uninstall the existing version and run the installer again by \
clicking on $\"Ok$\" or click on $\"Cancel$\" to abort this installation." \
/SD IDOK IDOK QuietUninstall IDCANCEL
Goto done
QuietUninstall:
ExecWait '"$INSTDIR\uninstall.exe" /S _=$INSTDIR'
Goto done
done:
abort
FunctionEnd
Adding the Goto done seems to still do the same thing and not abort where appropriate. I am about one week into this and was on a roll by Friday but then the weekend happened... Seem a lot of stuff I was learning and finally understanding with how NSIS is set up kind of got mushy in my brain over the weekend.
Is my approach all wrong here?
Red Wine
19th March 2007 17:27 UTC
try it like this,
!include "LogicLib.nsh"
Function ClientCheck
${If} ${FileExists} "$INSTDIR\File Upload Service\File.exe"
MessageBox MB_OKCANCEL|MB_ICONSTOP "You are trying to install over an existing installation \
of the Client.$\nPlease uninstall the existing version and run the installer again by \
clicking on $\"Ok$\" or click on $\"Cancel$\" to abort this installation." \
/SD IDOK IDCANCEL done
ExecWait '"$INSTDIR\uninstall.exe" /S _=$INSTDIR'
done:
Quit
${EndIf}
FunctionEnd
EDIT: Gee! sorry I didn't see it... it's Quit no abort :(
Zethris
19th March 2007 19:01 UTC
Slaps own forehead* doh! I forgot Quit too. Still this looks like a much better approach with how you have it.
That seems to work great and taught me something. Thanks.
I think they need to add an extra "major" to your ranking to show "major major dude" :D
One thing that this did bring up however, and maybe you might have a suggestion, is if they uninstall the software and have not yet reboot to remove the files that were previously untouchable as it was running as a service as I am sure you know windows has them on lock down.
What is happening is if they uninstall the program only to just re-install it right after, it is still detecting the software as being "installed" because the .exe file is still there.
We do need to actually still keep a semi-silent install of this software as it can be running on a server or a shared box that only can reboot at scheduled times. So a forced reboot is not going to work unfortunately.
Is there a way to detect if there is a "remove files after reboot" flag so that at a time they might uninstall and immediately after re-install, a message pop's up to instruct them to first reboot the machine before initiating another installation and quits once they click ok?
Or would you recommend rather than detecting a file like above, look for a registry entry that is more easily removable live while an uninstall is processing as apposed to a previously running service? edit: of course that still doesn't resolve the issue with the .exe file being there still, so I suspect that a reboot warning is necessary.
Red Wine
19th March 2007 19:22 UTC
Is there a way to detect if there is a "remove files after reboot" flag so that at a time they might uninstall and immediately after re-install, a message pop's up to instruct them to first reboot the machine before initiating another installation and quits once they click ok?
Regarding to the OS you should be able to check the winint.ini file (9x/Me) and the registry under HKLM "SYSTEM\ControlSet#\Control\Session Manager" "PendingFileRenameOperations" (NT).
Zethris
19th March 2007 19:41 UTC
Originally posted by Red Wine
Regarding to the OS you should be able to check the winint.ini file (9x/Me) and the registry under HKLM "SYSTEM\ControlSet#\Control\Session Manager" "PendingFileRenameOperations" (NT).
Yeah I think that approach would be best. Do you happen to know what the 001 and 002 under ControlSet# denotes when I looked at it under regedit? Are they for particular users?
Will it matter which one I use?
kichik
19th March 2007 19:47 UTC
You should always use CurrentControlSet which points to the currently used ControlSet and not ControlSet#. See KB100010 for more information about this.
Red Wine
19th March 2007 20:02 UTC
Thanks kichik, :) that's so clear and easy against my method where I had to enumerate ControlSets to find the value.
Zethris
19th March 2007 20:24 UTC
Aha! ok. Thanks Kichik and Red Wine!
Now, the point is, is to look for the actual key of "PendingFileRenameOperations" and if it is not present, then continue or if it is show the warning that they must reboot first, right?
Red Wine
19th March 2007 20:34 UTC
You should be able to determine,
a) if exists value data,
b) if the name of your exe exists in there.
For b see ${StrStr} into the included StrFunc.nsh
kichik
19th March 2007 20:43 UTC
PendingFileRenameOperations is REG_MULTI_SZ. It's not that simple to read it. You can create a reader based on the following example:
http://nsis.sourceforge.net/REG_MULTI_SZ_Reader
Red Wine
19th March 2007 21:22 UTC
This requires registry plugin,
http://nsis.sourceforge.net/Registry_plug-in
!define TEST_FILE "File.txt"
outfile boo.exe
!include "LogicLib.nsh"
!include "StrFunc.nsh"
!include "Registry.nsh"
${StrStr}
section
FileOpen $0 "$EXEDIR\${TEST_FILE}" w
Delete /rebootok "$EXEDIR\${TEST_FILE}"
${registry::Read} "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager"\
"PendingFileRenameOperations" $0 $1
MessageBox MB_OK "$0"
${registry::Unload}
${If} $0 != ""
StrLen $2 "${TEST_FILE}"
${StrStr} $1 "$0" "${TEST_FILE}"
StrCpy $3 $1 $2
MessageBox MB_OK "[$3]"
${AndIf} $3 == "${TEST_FILE}"
MessageBox MB_OK "please reboot"
${EndIf}
sectionend
Zethris
19th March 2007 21:56 UTC
Thank you guys very much for your help on this.