【问题标题】:Delete directory regardless of 260 char limit无论 260 字符限制如何删除目录
【发布时间】:2013-04-29 20:31:49
【问题描述】:

我正在编写一个简单的脚本来在一定天数后删除 USMT 迁移文件夹:

## Server List ##
$servers = "Delorean","Adelaide","Brisbane","Melbourne","Newcastle","Perth"

## Number of days (-3 is over three days ago) ##
$days = -3

$timelimit = (Get-Date).AddDays($days)

foreach ($server in $servers)
{
    $deletedusers = @()
    $folders = Get-ChildItem \\$server\USMT$ | where {$_.psiscontainer}
    write-host "Checking server : " $server
    foreach ($folder in $folders) 
    {
        If ($folder.LastWriteTime -lt $timelimit -And $folder -ne $null)
        {
            $deletedusers += $folder
            Remove-Item -recurse -force $folder.fullname
        }
    }
        write-host "Users deleted : " $deletedusers
        write-host
}

但是我一直在打可怕的Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

我一直在寻找解决方法和替代方案,但它们都围绕着我关心文件夹中的内容。

我希望有一个更简单的解决方案,因为如果文件夹内容被标记为删除,我并不真正关心它。

除了 Remove-Item -recurse 之外,是否有任何本机 Powershell cmdlet 可以完成我所追求的目标?

【问题讨论】:

    标签: powershell limit


    【解决方案1】:

    我经常在节点项目中遇到这个问题。它们嵌套了它们的依赖项,一旦 git 克隆,就很难删除它们。我遇到的一个不错的节点实用程序是rimraf

    npm install rimraf -g
    rimraf <dir>
    

    【讨论】:

    • 太棒了! robocopy 解决方案部分工作,它删除了一些文件,但不是全部。这个 rimraf 工作完美。非常感谢@Andy!
    【解决方案2】:

    正如 CADII 在另一个答案中所说:Robocopy 能够创建超过 260 个字符限制的路径。 Robocopy 也能够删除此类路径。您可以在路径上镜像一些包含过长名称的空文件夹,以防您想删除它。

    例如:

    robocopy C:\temp\some_empty_dir E:\temp\dir_containing_very_deep_structures /MIR
    

    这里是Robocopy reference了解参数和各种选项。

    【讨论】:

    • 我可以确认此解决方案有效,并且是我在遇到相同问题时使用的解决方案。
    • 非常感谢您!多年来,我一直在寻找一种工具来删除无用的文件夹名称。
    • 这应该是答案.. 它干净简洁,没有使用第三方工具
    • 这对我有用,但我必须在 robocopy 镜像后添加一个删除步骤(删除项目)。我留下了 E:\temp\dirname 和空的目录内容。非常感谢。我一直在努力解决这个问题!!!
    【解决方案3】:

    我创建了一个 PowerShell 函数,该函数能够使用提到的 robocopy 技术删除长路径 (>260):

    function Remove-PathToLongDirectory 
    {
        Param(
            [string]$directory
        )
    
        # create a temporary (empty) directory
        $parent = [System.IO.Path]::GetTempPath()
        [string] $name = [System.Guid]::NewGuid()
        $tempDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)
    
        robocopy /MIR $tempDirectory.FullName $directory | out-null
        Remove-Item $directory -Force | out-null
        Remove-Item $tempDirectory -Force | out-null
    }
    

    用法示例:

    Remove-PathToLongDirectory c:\yourlongPath
    

    【讨论】:

    • 仅供参考:在内部版本号为 14393(周年更新)的 Windows 10 中,.NET 中的路径限制错误已得到修复。您需要在本地策略中启用长路径支持,您可以使用长路径做任何您想做的事情,而无需求助于 P/Invoke 或 robocopy
    • 这就像一场梦。几个月来我一直在使用 subst z: myLongPath
    • 这是此页面上唯一对我有用的解决方案。谢谢!
    • 如果目录在 Windows Server 2016 中怎么办?
    【解决方案4】:

    SuperUser 上的这个答案为我解决了这个问题:https://superuser.com/a/274224/85532

    Cmd /C "rmdir /S /Q $myDir"
    

    【讨论】:

    • 这个答案过去曾为我工作过几次,但未能删除我的 node_modules 文件夹。对于那种情况,我求助于this other answer,因为无论如何我都安装了节点。
    • 对我也不起作用。它也有可能会因带有空格的目录删除错误的内容而失败(尽管这是可以修复的)
    【解决方案5】:

    我不久前学到了一个技巧,它通常可以解决长文件路径问题。显然,当使用某些 Windows API 的某些功能时,将流经无法处理长文件名的遗留代码。但是,如果您以特定方式格式化路径,则可以避免遗留代码。解决这个问题的技巧是使用“\\?\”前缀来引用路径。应该注意的是,并非所有 API 都支持这一点,但在这种特殊情况下它对我有用,请参见下面的示例:

    以下示例失败:

    PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden
    
    
    Directory: D:\System Volume Information\dfsr
    
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a-hs        10/09/2014  11:10 PM     834424 FileIDTable_2
    -a-hs        10/09/2014   8:43 PM    3211264 SimilarityTable_2
    
    PS D:\> Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
    Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260
    characters, and the directory name must be less than 248 characters.
    At line:1 char:1
    + Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (D:\System Volume Information\dfsr:String) [Remove-Item], PathTooLongExcepti
    on
    + FullyQualifiedErrorId : RemoveItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
    
    PS D:\>
    

    但是,在路径前加上“\\?\”可以使命令成功运行:

    PS D:\> Remove-Item -Path "\\?\D:\System Volume Information\dfsr" -recurse -force
    PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden
    PS D:\>
    

    【讨论】:

    • 这是一个绝妙的技巧。我得试一试。当我遇到限制时,我通常不会做任何太奇特的事情,主要只是解析文件夹结构或删除文件等。谢谢!
    • 我没有收到任何错误,但它也没有删除文件夹。
    • 这对我有用的前缀,win 10 powershell 5.1。像这样 Remove-Item -Recurse -Force -Path "\\?\$($_.FullName)"
    • 在 PS 5.1 上删除具有长路径的文件夹,但在 PS 7.1 上不删除(无错误)(在 Windows Server 2019 上)
    • PS 7.1 (core) 能够删除没有前缀的文件夹。 (在 Windows Server 2019 上)
    【解决方案6】:

    如果你安装了 ruby​​,你可以使用 Fileman:

    gem install fileman
    

    安装后,您只需在命令提示符下运行以下命令:

    fm rm your_folder_path
    

    当您在 Windows 上使用 node.js 进行开发时,这个问题确实令人头疼,因此 fileman 变得非常方便,可以偶尔删除所有垃圾

    【讨论】:

    • 这是针对特定情况的一个很好的答案,但不幸的是,它们当时是生产服务器,没有红宝石!
    • 荒谬的是,我必须安装 Ruby,然后是 devkit,然后是 gem 才能删除文件夹,但这确实完成了工作。
    • 这太棒了。它在几分之一秒内删除了一棵巨大的树。谢谢,谢谢,谢谢。
    【解决方案7】:

    这是PowerShell 的已知限制。解决方法是使用dir cmd(抱歉,这是真的)。​​

    http://asysadmin.tumblr.com/post/17654309496/powershell-path-length-limitation

    或如 AaronH 回答中提到的,在此示例中使用 \?\ 语法来删除构建

    dir -Include build -Depth 1 | Remove-Item -Recurse -Path "\\?\$($_.FullName)"
    

    【讨论】:

    【解决方案8】:

    如果你正在做的只是删除文件,我会使用一个函数来缩短名称,然后我会删除。

        function ConvertTo-ShortNames{
        param ([string]$folder)
        $name = 1
        $items = Get-ChildItem -path $folder
        foreach ($item in $items){
            Rename-Item -Path $item.FullName -NewName "$name"
            if ($item.PSIsContainer){
                $parts = $item.FullName.Split("\")
                $folderPath = $parts[0]
                for ($i = 1; $i -lt $parts.Count - 1; $i++){
                    $folderPath = $folderPath + "\" + $parts[$i]
                }
                $folderPath = $folderPath + "\$name"
                ConvertTo-ShortNames $folderPath
            }
            $name++
        }
    }
    

    我知道这是一个老问题,但我想我会把它放在这里以防有人需要它。

    【讨论】:

    • 这适用于 Windows 机器上的 node_modules 文件夹。
    • 救世主。谢谢!
    • "以防有人需要。"把它放进去。顺便说一句,很好的解决方案。 ( :
    【解决方案9】:

    有一种解决方法是使用来自Base Class Libraries 项目的 Experimental.IO。您可以在poshcode 上找到它,或从author's blog 下载。 260 限制源自 .NET,因此要么是这个,要么是使用不依赖于 .NET 的工具(如 @Bill 建议的 cmd /c dir)。

    【讨论】:

      【解决方案10】:

      工具组合效果最好,尝试使用 dir /x 来获取 8.3 文件名。然后,您可以将该输出解析为文本文件,然后构建一个 powershell 脚本来删除您输出文件的路径。陪你一分钟。或者,您可以将 8.3 文件名重命名为更短的名称,然后删除。

      【讨论】:

        【解决方案11】:

        因为我的 Robocopy 在 1、2 和 3 中工作

        1. 首先创建一个空目录,比如说 c:\emptydir
        2. ROBOCOPY c:\emptydir c:\directorytodelete /purge
        3. rmdir c:\directorytodelete

        【讨论】:

          【解决方案12】:

          这已经过时了,但我最近不得不再次解决它。我最终使用了“subst”,因为它不需要在运行它的 PC 上提供任何其他模块或功能。更便携一点。

          基本上找到一个备用驱动器号,“替换”到该字母的长路径,然后将其用作 GCI 的基础。

          唯一的限制是 $_.fullname 和其他属性会将驱动器号报告为根路径。

          似乎工作正常:

          $location = \\path\to\long\
          $driveLetter = ls function:[d-z]: -n | ?{ !(test-path $_) } | random
          
          subst $driveLetter $location
          sleep 1
          Push-Location $driveLetter -ErrorAction SilentlyContinue
          Get-ChildItem -Recurse
          
          subst $driveLetter /D
          

          那个命令显然不是删除文件而是可以替代的。

          【讨论】:

            【解决方案13】:

            PowerShell 可以很容易地与 AlphaFS.dll 一起使用来执行实际的文件 I/O 操作 没有 PATH TOO LONG 的麻烦。

            例如:

            Import-Module <path-to-AlphaFS.dll>
            
            [Alphaleonis.Win32.Filesystem.Directory]::Delete($path, $True)
            

            有关此 .NET 项目,请参阅 Codeplex:https://alphafs.codeplex.com/

            【讨论】:

              【解决方案14】:

              添加到 Daniel Lee 的解决方案中, 当 $myDir 中间有空格时,考虑到从空间中拆分的文件集,它会给出 FILE NOT FOUND 错误。为了克服这个问题,请在变量周围使用引号并放置 powershell 转义字符以跳过 quatations。

              PS&gt;cmd.exe /C "rmdir /s /q &lt;grave-accent&gt;"$myDir&lt;grave-accent&gt;""

              请用正确的重音字符代替&lt;grave-accent&gt;
              SO 和我一起玩,我不能添加它:)。希望有人会更新它以便其他人容易理解

              【讨论】:

                【解决方案15】:

                为了完整起见,我已经多次遇到此问题,并结合使用“subst”和“New-PSDrive”在各种情况下解决它。

                不完全是一个解决方案,但如果有人正在寻找替代方案,这可能会有所帮助。

                Subst 似乎对您使用哪种类型的程序来访问文件非常敏感,有时有效,有时无效,似乎与 New-PSDrive 相同。

                【讨论】:

                  【解决方案16】:

                  任何使用 .NET 开箱即用开发的东西都会因路径太长而失败。您必须将它们移至 8.3 namesPInVoke (Win32) calls,或使用 robocopy

                  【讨论】:

                    【解决方案17】:

                    我在尝试删除远程计算机上的文件夹时遇到了同样的问题。

                    没有任何帮助,但...我发现了一个窍门:

                    # 1:let's create an empty folder
                    md ".\Empty" -erroraction silentlycontinue
                    
                    # 2: let's MIR to the folder to delete : this will empty the folder completely.
                    robocopy ".\Empty" $foldertodelete /MIR /LOG+:$logname 
                    
                    # 3: let's delete the empty folder now:
                    remove-item $foldertodelete -force
                    
                    # 4: we can delete now the empty folder
                    remove-item ".\Empty" -force
                    

                    在本地或远程文件夹(使用 UNC 路径)上的作用就像魅力一样

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-04-14
                      • 2014-03-01
                      • 2021-12-19
                      • 1970-01-01
                      • 2020-07-26
                      • 2021-08-29
                      • 2017-07-09
                      相关资源
                      最近更新 更多