我的NSIS脚本的卸载不会删除ProgramData目录中的链接

时间:2011-08-10 21:32:49

标签: nsis uninstall

得到另一个新手NSIS问题。这是脚本:

; -*-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

卸载似乎有效,除了将快捷方式保留在ProgramData:

之外
 Directory of c:\ProgramData\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

我的剧本出错了是什么让这些东西不知所措?

以下是卸载程序写入其控制台的内容(我添加了一个列出$ SMPROGRAMS的DetailPrint消息):

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

因此,ProgramData下的链接永远不会被引用,它正在寻找AppData \ Roaming下的链接。

我正在Windows 7上对此进行测试,但这里的核心问题是我希望能够编写一个适用于从XP到Windows 7的所有内容的脚本,而不管Windows中的所有内容如何变化不同版本的不同点。这看起来可能很痛苦。

2 个答案:

答案 0 :(得分:3)

如果将DetailPrint添加到nsis脚本中,则很明显NSIS会尝试在C:\Users下创建文件,但它们实际上是在c:\ProgramData中创建的。这个ProgramData目录很奇怪,因为它dir C:\不可见,但是可以使用cd进入目录。这些谜团是由 Virtual Store 引起的,这是Windows 7的一个棘手功能。

现在解决方案。 Windows应用程序应定义其执行级别,否则系统可能会以意外的方式运行。您还记得一些应用程序询问是否仅为当前用户安装&#34;&#34;或者&#34;对于所有用户&#34;?这是我们需要宣布的事情。

如果我们插入nsis指令RequestExecutionLevel user,则会为当前用户创建快捷方式。如果我们执行RequestExecutionLevel admin,那么我们还应该在安装和卸载部分添加SetShellVarContext all

这个答案是基于来自nsis wiki的文章:Shortcuts removal fails on Windows Vista,其中给出了两种方法的例子。

答案 1 :(得分:0)

来自规范:

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.

尝试将/r添加到RMDir行以强制它刷新内容。这个或者单独删除链接。