我的NSIS脚本';s卸载isn';t从ProgramData目录中删除链接

我的NSIS脚本';s卸载isn';t从ProgramData目录中删除链接,nsis,uninstallation,Nsis,Uninstallation,还有一个新来的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 ins

还有一个新来的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
因此,ProgramData下的链接从未被引用,而是在AppData\Roaming下查找链接

我正在Windows7上进行测试,但这里的核心问题是,我希望能够编写一个适用于从XP到Windows7的所有程序的脚本,而不管Windows如何在不同版本的不同位置存储内容。这看起来可能很痛苦。

根据规范:

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行以强制其刷新内容。如果nsis脚本中添加了
DetailPrint
,nsis显然会尝试在
C:\Users
下创建文件,但它们实际上是在
C:\ProgramData
中创建的。这个
ProgramData
目录很奇怪,因为它在
dir C:\
中不可见,但是可以使用
cd
进入目录。这些谜团是由虚拟商店引起的,虚拟商店是Windows7的一个棘手的功能

现在来看看解决办法。Windows应用程序应该定义它们的执行级别,否则系统可能会以意外的方式运行。您还记得有些应用程序询问是“仅针对当前用户”还是“针对所有用户”安装吗?这是我们需要申报的东西

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


这个答案基于nsis wiki的文章:,其中给出了两种方法的示例。

这是在什么操作系统上发生的?XP?远景Windows 7?他删除了他创建的所有文件,因此不需要/r开关。问题是目录被映射,快捷方式被创建在不同的位置。使用
RMDir/r
时请非常小心。它应该经过深思熟虑,而不是鲁莽地应用。
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.