Archive: Uninstall fails under Windows 7


Uninstall fails under Windows 7
Hi

I created an installer which runs just fine. I installed the application as standard user under Windows 7 into the suggested installation directory C:\Users\testUser\AppData\Local\MyApp.
Now I'd like to uninstall the application. The summary page shows the following:

Delete file: C:\Users\testUser\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp\Uninstall MyApp.lnk
Delete file: C:\Users\testUser\AppData\Local\MyApp\uninstall.exe
Delete on reboot: C:\Users\testUser\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp
Delete on reboot: C:\Users\testUser\AppData\Local\MyApp\
Completed


Basically, only the uninstall.exe and the short cut in the start menu referring to the uninstaller are removed. The whole application remains there - even after a reboot.
However, all the files can be manually removed without any problem.

Additional information:
The execution level in the nsis-script is set to:
!define MULTIUSER_EXECUTIONLEVEL Highest

The same procedure works as expected under Windows Vista.

Anybody knows what's going on here?

Thanks
Remo


Where are your program files stored?

Stu


I'm not sure whether I understand your question correctly, but the program files are stored under C:\Users\testUser\AppData\Local\MyApp, that's the default installation path NSIS suggests when the installer is executed as standard user.


Yes that's what I meant. How about doing some test on $INSTDIR. Try writing to it using FileOpen and see what happens. Either the path is wrong or you do not have write access.

Stu


The installer does edit some files in $INSTDIR during installation, which works well. You mean I should try to edit files in the uninstaller?
What's the execution level requested by the uninstaller? The same that I specified for the installer? Or can / should I also specify one for the uninstaller?


RequestExecutionLevel puts the manifest in both the installer and uninstaller. Yes, see if you can write to $INSTDIR in the uninstaller. Also check $INSTDIR is correct (i.e. MessageBox)

Stu


I added the following to section -un.post:

FileOpen $0 $INSTDIR\file.dat w
FileClose $0
MessageBox MB_OK "$INSTDIR\file.dat"
Delete $INSTDIR\file.dat


As expected, the file is being written to C:\Users\testUser\AppData\Local\MyApp, the message box with C:\Users\testUser\AppData\Local\MyApp\file.dat is shown and the file is removed afterwards.

I still have no clue why the other files cannot be removed by the uninstaller. According to the file properties (security tab), the current user has full rights on all of them.
And again, the same installer/uninstaller runs perfectly well under Windows Vista.

Thanks for further help
Remo


Try a ClearErrors before a Delete instruction then check if the error flag is set afterwards. Also have you tried manually deleting the files?

Stu


Stu, as I mentioned in my first post, all the files can be deleted manually. But I tried your suggestion. The error flag is not set after trying to execute

RmDir /REBOOTOK $INSTDIR

Further ideas?


Try with /r ?

Stu


Yep that's it!
I created the NSIS script with an eclipse wizard. Strange that it didn't generate a /r. But also: why did it work with Vista?

Anyway, thanks for your help!


note: It is extremely dangerous to use RmDir /r. If your $INSTDIR happens to be, say, Program Files, you will do massive damage to the user's OS. You should not use RmDir /r. You should only delete the files you KNOW you want to delete.


That's a good point. But you don't want to explicitly enumerate every single file in your installer/uninstaller, do you?


No but you should really only delete exactly what you know you've installed and nothing else. I was only suggesting trying /r to fix your problem but as MSG says it is not a solution for uninstalling.

You can do checks on $INSTDIR like this demonstrates (maybe a bit over the top though looking at it now):
http://nsis.sourceforge.net/Validati...fore_uninstall

Stu


Originally posted by hürnen
That's a good point. But you don't want to explicitly enumerate every single file in your installer/uninstaller, do you?
Actually I would say 'yes' to this. Even if there's hundreds of them, safety comes first in my opinion.

Originally posted by hürnen
That's a good point. But you don't want to explicitly enumerate every single file in your installer/uninstaller, do you?
There -are- headers that help you with this...

http://nsis.sourceforge.net/Uninstal...nstalled_files
Uses custom file manipulation macros and records them as you go.
( we use a similar but more flexible technique so that File /r and File with wildcards can still be used, which also keeps track of registry keys and such.. messy, though )

http://nsis.sourceforge.net/Advanced...og_NSIS_Header
Uses file enumeration -before- installation and -after- installation, and records the difference. This works with File /r and File with wildcards, but incurs either a small or a large hit depending on how long it takes to enumerate your target folder.
( in our case, an add-on for a larger program which carries thousands of files and enumeration, if the OS didn't have anything cached yet, was simply too slow )

I also started a new header for exactly this sort of thing, as well as handling backing up of existing files, etc. But it's a right pain to write (it's been collecting dust as other priorities have taken over); although perhaps trying to do everything with defines to keep compiled code as clean as possible may be the wrong approach. I still think a pre-file write and post-file write callback within NSIS would be great.