|
|
|
|
#1 |
|
Junior Member
Join Date: Jan 2011
Posts: 11
|
Uninstall
Hello
After the installation, it is possible that some folders are added in the Directory from the user where I installed my files. So i don't know all the files and folders which i've to delete with my uninstaller. Additionaly I unzipp some folder, so there ara a lot of files after the Installation. I'm using the Modern UI. At the moment my uninstaller looks like: RMDir /r $INSTDIR\Installation RMDir /r $INSTDIR\play RMDir /r $INSTDIR\myfolder I know it is a bit dangerous. I searched a while and only found the "Uninstall only installed files" unlist.nsi. But this function only create a list during the installation. And i'm looking for creating a list during uninstallation, while some files and order are added after my installation. Does it already exist a function which search every file and folder in the installed directory and delete each file? Maybe I missed a simple plug-in or something similar? Thanks and Regards, Wili |
|
|
|
|
|
#2 | |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
Quote:
If you don't know what you want to delete, Delete /r is the only possible solution. This probably means that you need to change your application, so that you DO know what you want to delete. |
|
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Jan 2011
Posts: 11
|
Hi
Thanks for your answer. Does theire exist a function which generate a list of all files and folders during the Uninstall Section? Thanks and Regards, Marco |
|
|
|
|
|
#4 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
What I would do is write a small program (it could be a silent NSIS executable) and run it at compile time using !system. It will simply write the NSIS File instructions to one file (which you !include in your install section(s)) and the NSIS Delete instructions to another file (which you !include in your uninstall section(s)). If you write the executable in NSIS, you can use Locate (look in the manual). Job done.
Stu |
|
|
|
|
|
#5 |
|
Junior Member
Join Date: Jan 2011
Posts: 11
|
Thanks a lot for your hints.
I'll change my uninstaller Ideas. Last Question, is it possible to figure when unistaller.exe is launched, on with path it was stored? The $EXEPATH, etc. shows the path where it is executed. But I'm looking to read out, where the uninstaller was store. Is theire a simple way? Thanks and regards, Marco |
|
|
|
|
|
#6 |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
In the uninstaller, $INSTDIR contains the directory of uninstall.exe. (Note: This is also why it's so dangerous to do RmDir /r $INSTDIR, because someone might have moved uninstall.exe to Program Files!)
You can store the actual installation directory in an ini file or the registry, during installation. (You can also use that to check if uninstall.exe has been moved, before you start the uninstallation.) |
|
|
|
|
|
#7 |
|
Junior Member
Join Date: Jan 2011
Posts: 11
|
Thanks a lot.
So i'll check if the uninstaller.exe is still at the same folder (with filexists...). Regards, Marco |
|
|
|
|
|
#8 |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
What would you want to do with FileExists? o_O
ReadRegStr $0 HKLM YourRegKey YourRegString ${If} $0 != $INSTDIR MessageBox MB_OK "Warning here" ${EndIf} |
|
|
|
|
|
#9 |
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
I have realised the danger of RMDir /r "$INSTDIR", even if it is a really small possibility that a user move the Uninstall.exe to another directory...
so I thought about a solution for my script and just replace the $INSTDIR with value from the registry. My questions: Why does this not work? (the installdir is untouched after uninstall is finished - nothing is deleted! but the key is there and is been showed "MessageBox MB_OK "echo - $0") and: is there another universal solution? example: PHP Code:
|
|
|
|
|
|
#10 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
If you checked the value of $0 you'd know. You've put quotes around the value in the registry. Also your script is just as bad as using $INSTDIR. If someone deletes that registry value, RMDIR will be given an empty string, i.e. the root and delete EVERYTHING. Please either avoid RMDir completely or do at least some validation on the path you are giving it.
Stu |
|
|
|
|
|
#11 | ||
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
hi
-but RMDir /r "$INSTDIR" have also quotes and it works,... the $0 includes the "" so i removed them in the script -> RMDir /r $0 Quote:
I think, the best way will be to check that the last dir is ..."/MyProgram" to make sure the User didnt use "C:\" or "C:\Program Files" as installation directory!? but how to do it? btw. That some one deletes the Reg entry is very unlikely, IMHO -------------- I have testet your Example: http://nsis.sourceforge.net/Uninstal...nstalled_files But it does not work. I guess it is because of * or *.* This is what i use in my script: PHP Code:
when i try to use your script, the compiller breaks with: Quote:
The line of error: ${File} /r "${BIN}\*" bye |
||
|
|
|
|
|
#12 |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
The regentry not existing is actually far more likely than a user moving uninstall.exe. And the consequences if it happens are far far worse. So summing up, your method is extremely dangerous. (Example: User installs to D:\Software\YourApp, then formats C: and reinstalls windows, then runs your uninstaller. As you can see, this could happen very easily.)
Here's what I do: PHP Code:
And together with the above code, I NEVER use RmDir /r, no matter how badly I want to. I only delete the files I know I should delete. Nothing else. It's just a matter of courtesy to your users that you don't take frivolous risks with their computers. Even if it means leaving some files behind after uninstall, there's just no excuse to risk destroying someone's OS. |
|
|
|
|
|
#13 |
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
This doesn't cover the case when the user installed the app in C:\ ...
![]() hmm, so ideally the installer should delete 1 file at the time, and delete directory's only if the dir is empty? Thanks for the example. I will use it in my script. But what i don't understand is the "$ALLUSERS == 1" thing. I didn't find this Variable in the manual. Is this automatically detected when "SetShellVarContext all" is set previously? or do i need a "!include ..." to use this? bye |
|
|
|
|
|
#14 | |||
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
Quote:
Quote:
Quote:
Single-user installations' ARP info is stored in HKCU, actually. |
|||
|
|
|
|
|
#15 | ||||
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Quote:
Quote:
Quote:
Quote:
Stu |
||||
|
|
|
|
|
#16 | ||
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
Quote:
The manual don't show any necessary format: http://nsis.sourceforge.net/Docs/Chapter4.html#4.9.1.8 -------- Quote:
Cant i just use the ${File} ..\* for the app and any sub directory? will this delete/uninstall those sub dirs as well? ------ by ignore you mean to skip the IF? like this: PHP Code:
|
||
|
|
|
|
|
#17 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Ignore that $ALLUSERS bit. Uninstall registry is always under HKLM.
Stu |
|
|
|
|
|
#18 | ||
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Quote:
Quote:
Stu |
||
|
|
|
|
|
#19 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Also remember the uninstall code needs to delete in reverse order to the order that the files were extracted/created. E.g.
Stucode: |
|
|
|
|
|
#20 | |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Quote:
Edit: And for all this time I've been avoiding add/remove programs and using an Uninstall short-cut only lol. Thanks ![]() Stu |
|
|
|
|
|
|
#21 | |
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
so back to my question: what do i need to use the "$ALLUSERS == 1"
Your example is working in my installer, when i move the deinstaller to another location the MassageBox pops out. There is only a tiny flaw... the compiler shows a warning: Quote:
btw. the '"$INSTDIR\myprogram.exe"' only happened because i copy-pasted this line from another script. I removed the quotes from all WriteRegStr and now its working perfectly! thanks |
|
|
|
|
|
|
#22 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
MSG was just giving you an idea to use that variable to indicate an all users / current user install. Doesn't mean you need to use it.
Stu |
|
|
|
|
|
#23 |
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
I have modified the example a little bit. This is what i use:
PHP Code:
I think, together with the Path saved in the RegKey and the user feedback, it is a good compromise. |
|
|
|
|
|
#24 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
I would add a ClearErrors above ReadRegStr just in case you later add code which may set the error flag. Also, should that not be an OR (you are implying an AND by using two If statements. I.e. it should be If $2 != $INSTDIR OR !FileExists $INSTDIR\MyProgram.exe). With your code, if someone moves the uninstall executable to another folder with a MyProgram.exe in it (unlikely I know), then the uninstall will continue.
Stu |
|
|
|
|
|
#25 |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
Stu: That depends on what you decide is more important. If my regentry is there and the value matches $instdir, then I don't check which files are there. This is in order to support rollback in case of installation failure (the regkey is created first thing during installation). But yeah, Or might be the better option generally speaking.
|
|
|
|
|
|
#26 |
|
Junior Member
Join Date: Apr 2008
Posts: 21
|
Thanks for the tip, i extended the script with the ClearErrors, changed it to an OR case and added a check for the RegKey existence in "un.onInit". But i dont get the result i expected.
1. Question: Why is ${Usedinstpath} defined, even if it is "jumped" by a GOTO? (in the un.onInit part) 2. Question: Why does the Uninstaller not delete the directory that is defined in $2 and ${Usedinstpath}? (the App Directory remains untouched after successful uninstallation) PHP Code:
|
|
|
|
|
|
#27 | |
|
Major Dude
Join Date: Oct 2006
Posts: 1,892
|
Quote:
Because "$2" is not a define, so "!ifdef $2" is always false and the compiler completely skips the RmDir command. You need to use ${If} $2 != "" . Once again, you're confusing compiletime with runtime. |
|
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|