【问题标题】:How to make NSIS RMDir operate on subdirectories?如何使 NSIS RMDi 对子目录进行操作?
【发布时间】:2010-07-21 04:18:06
【问题描述】:

在 NSIS 安装程序脚本中,我有:

RMDir "$INSTDIR"

现在,如果用户将安装目录设置为C:\Program Files\Product,它可以正常工作,但是如果他们安装到更深的位置,例如C:\Program Files\Company\Product,RMDir 会删除“产品”而不是“公司”。我怎样才能让它删除每个空目录到根目录(不使用/r)......例如如果为空则删除 Product,如果为空则删除 Company,如果为空则删除 Program Files,等等?


编辑:我最终使用的功能:

# Delete empty directories recursively
var deleteDir
var dirLength
Function un.PathDeleteEmptyDirRecurse
ClearErrors
loop:
    Sleep 50 ; Without a small delay here, the directory sometimes won't get removed
    RMDir "$deleteDir" ; Remove the directory
    IfErrors end
    strlen $dirLength $deleteDir ; Store the length of the path
    intcmp $dirLength 3 end end ; If the length of the path is <= 3 (e.g. C:\), we're at the root drive
    GetFullPathName $deleteDir "$deleteDir\.." ; <path>\.. results in the parent directory of <path>
    IfErrors end loop
end:
FunctionEnd

【问题讨论】:

    标签: nsis


    【解决方案1】:

    我假设您希望在卸载程序而不是安装程序中使用它:

    Function un.PathDeleteEmptyDirRecurse 
    exch $0
    push $1
    ClearErrors
    loop:
    RMDir $0
    IfErrors end
    strlen $1 $0
    intcmp $1 3 end end ;root of drive?
    GetFullPathName $0 "$0\.."
    IfErrors end loop
    end:
    pop $1
    pop $0
    FunctionEnd
    
    ...
    
    push $instdir
    call un.PathDeleteEmptyDirRecurse
    

    【讨论】:

    • 谢谢,这很好用,除了一件事:我如何连续调用两次? push $instdir1 \ call un.PathDeleteEmptyDirRecurse \ push $instdir2 \ call un.PathDeleteEmptyDirRecurse(使用\模拟换行符)不起作用。
    • @Jake Petroules:当我尝试时工作正常:nsis.pastebin.com/5JgDwcEH(您必须从树中的 最深 文件夹开始)
    • 我是从最深的文件夹开始的……非常令人费解。这就是我在 NSIS 脚本中的内容:nsis.pastebin.com/1scSjsgM
    • 我在回答中添加了对 ClearErrors 的调用,我认为这就是问题所在
    • 显然不是。然而,非常奇怪的是,如果我在 RMDir 之前添加一个MessageBox MB_OK "$0" 命令,则可以删除目录。它还表明它正在删除我想要的文件夹(例如消息框显示 C:\path\to\the\folder),但 RMDir 根本不起作用。
    【解决方案2】:

    这是我使用的;

    Function un.RMDirUP
      !define RMDirUP '!insertmacro RMDirUPCall'
      !macro RMDirUPCall _PATH
          push '${_PATH}'
          Call un.RMDirUP
      !macroend
    
      ; $0 - current folder
      ClearErrors
      Exch $0
      RMDir "$0\.."
      IfErrors Skip
      ${RMDirUP} "$0\.."
      Skip:
      Pop $0
    FunctionEnd
    

    这让你在卸载时调用它 ${RMDirUP} "$INSTDIR"

    【讨论】:

      【解决方案3】:

      我最后只用这两行删除了安装目录和目录本身(如果为空)中的所有内容

      RMDir /r "$INSTDIR"
      RMDir "$INSTDIR\..\."
      

      【讨论】:

      • 这很危险。如果您的用户选择安装到 c:\ 或 c:\program files\ 会发生什么?您刚刚删除了该文件夹中的所有文件和子目录。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 2017-03-18
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多