开发者

My NSIS script's Uninstall isn't deleting links from ProgramData directory

开发者 https://www.devze.com 2023-03-27 10:22 出处:网络
Got another newbie NSIS question. Here\'s the script: ; -*-nsis-*- Name \"ndhtest\" OutFile \"FooStartMenuTest.exe\"

Got another newbie NSIS question. Here's the script:

; -*-nsis-*-    
Name "ndhtest"
OutFile "FooStartMenuTest.exe"    
XPStyle on
!define FOO_SRC c:\users\nhughes\foo

InstallDir "$PROGRAMFILES\Initech\"
Icon ${FOO_SRC}\foo_logo.ico
UninstallIcon ${FOO_SRC}\uninstall.ico

Page instfiles
UninstPage uninstConfirm
UninstPage instfiles

Section
  SetOutPath $INSTDIR
  File ${FOO_SRC}\foo.bat
  WriteUninstaller "$INSTDIR\uninstall.exe"
  CreateDirectory $SMPROGRAMS\Initech
  CreateShortCut $SMPROGRAMS\Initech\Foo.lnk $INSTDIR\foo.bat "" \
    "${FOO_SRC}\foo_logo.ico"
  CreateShortCut $SMPROGRAMS\Initech\Uninstall.lnk $INSTDIR\uninstall.exe "" \
    "${FOO_SRC}\uninstall.ico"
SectionEnd

Section "Uninstall"
  Delete $SMPROGRAMS\Initech\Foo.lnk
  Delete $SMPROGRAMS\Initech\Uninstall.lnk
  RMDir $SMPROGRAMS\Initech
  Delete $INSTDIR\Foo.bat
  Delete $INSTDIR\uninstall.exe
  RMDir $INSTDIR
SectionEnd

The uninstall seems to work except for leaving the shortcuts under ProgramData:

 Directory of c:\Pro开发者_如何学JAVAgramData\Microsoft\Windows\Start Menu\Programs\Initech

08/10/2011  04:07 PM    <DIR>          .
08/10/2011  04:07 PM    <DIR>          ..
08/10/2011  04:23 PM             1,847 Foo.lnk
08/10/2011  04:23 PM             1,885 Uninstall.lnk
               2 File(s)          3,732 bytes
               2 Dir(s)  1,387,345,117,184 bytes free

What is my script getting wrong that is leaving this stuff hanging around?

Here is what the uninstaller writes to its console (I added a DetailPrint message listing $SMPROGRAMS):

smprograms=C:\Users\nhughes\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Remove folder: C:\Users\nhughes\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Initech\
Delete file: C:\Program Files (x86)\Initech\foo.bat
Delete file: C:\Program Files (x86)\Initech\uninstall.exe
Remove folder: C:\Program Files (x86)\Initech\
Completed

So the links under ProgramData never get referred to, it's looking for the links under AppData\Roaming instead.

I'm testing this on Windows 7, but the core problem here is I would like to be able to write a script that works on everything from XP to Windows 7, regardless of all the changes in how Windows squirrels away stuff in different spots in different versions. This is looking like it might be painful.


If DetailPrint is added to the nsis script, it starts to be apparent that NSIS tries to create the files under C:\Users, but they are actually created in c:\ProgramData. This ProgramData directory is a strange thing, because it's not visible with dir C:\, however it's possible to enter the directory with cd. Such mysteries are caused by Virtual Store, a tricky feature of Windows 7.

Now to the solution. Windows applications should define their execution level, otherwise system may behave in an unexpected way. You remember some applications ask whether to install "for current user only" or "for all users"? That's the thing we need to declare.

If we insert nsis instruction RequestExecutionLevel user, then the shortcuts are made for current user. If we do RequestExecutionLevel admin, then we should also add SetShellVarContext all to both install and uninstall sections.

This answer is based on the article from nsis wiki: Shortcuts removal fails on Windows Vista, where examples are given for both approaches.


From the spec:

4.9.1.8 RMDir

[/r] [/REBOOTOK] directory_name

Remove the specified directory (fully qualified path with no wildcards). Without /r, the directory will only be removed if it is completely empty. If /r is specified, the directory will be removed recursively, so all directories and files in the specified directory will be removed. If /REBOOTOK is specified, any file or directory which could not have been removed during the process will be removed on reboot -- if any file or directory will be removed on a reboot, the reboot flag will be set. The error flag is set if any file or directory cannot be removed.

Try adding the /r to the RMDir lines to force it to flush the contents. Either that or remove the links individually.

0

精彩评论

暂无评论...
验证码 换一张
取 消