首页 > 解决方案 > 在现有文件上设置属性时出现错误“找不到路径的一部分”

问题描述

我编写了一个 powershell 脚本来从一组指定的根路径中的所有文件中删除 R/H/S 属性。相关代码为:

$Mask = [System.IO.FileAttributes]::ReadOnly.Value__ -bor [System.IO.FileAttributes]::Hidden.Value__ -bor [System.IO.FileAttributes]::System.Value__
Get-ChildItem -Path $Paths -Force -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
    $Value = $_.Attributes.value__
    if($Value -band $Mask) {
        $Value = $Value -band -bnot $Mask
        if($PSCmdlet.ShouldProcess($_.FullName, "Set $([System.IO.FileAttributes] $Value)")) {
            $_.Attributes = $Value
        }
    }
}

这很好用,但是在处理一个非常大的文件夹结构时,我遇到了一些这样的错误:

Exception setting "Attributes": "Could not find a part of the path 'XXXXXXXXXX'."
At YYYYYYYYYY\Grant-FullAccess.ps1:77 char:17
+                 $_.Attributes = $Value
+                 ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

我觉得这很奇怪,因为FileInfo被操作的对象保证存在,因为它来自文件搜索。

我不能给出文件名,因为它们是机密的,但我可以说:

您对可能导致这种情况的原因有什么建议吗?我假设如果完整路径太长,或者我没有对该文件的写入权限,则会引发更合适的错误。

标签: powershell

解决方案


正如您自己的回答中所述,问题原来是一条过长的路径(超过了 259 个字符的传统限制。)

除了通过Group Policy启用长路径支持之外,您还可以通过注册表在每台计算机上启用它,如下所示,这需要以提升(以管理员身份)运行:

# NOTE: Must be run elevated (as admin).
# Change will take effect in FUTURE sessions.
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled 1

通过0关闭支持。


但是,即使关闭了长路径支持(Windows 10 之前的版本总是如此),也可以处理长路径:

  • Windows PowerShell(PowerShell 最高版本 5.1)中,您必须使用长路径选择加入前缀,\\?\,如下所述。

  • PowerShell [Core] v6+中,不需要额外的工作,因为它始终支持长路径- 您既不需要打开支持系统范围,也不需要下面讨论的长路径前缀。

    • 警告:虽然原则上您也可以\\?\PowerShell [Core] 中使用,但从 v7.0.0-rc.2 开始,对它的支持不一致;看到这个 GitHub 问题

重要提示:前缀\\?\仅在以下条件下有效:

  • 前缀路径必须是完整(绝对)规范化路径(不得包含...组件)。

    • 例如,\\?\C:\path\to\foo.txt有效,但\\?\.\foo.txt无效。
    • 此外,如果路径是UNC路径,则路径需要不同的形式:
      • \\?\UNC\<server>\<share>\...;
      • 例如,\\server1\share2必须表示为\\?\UNC\server1\share2

推荐阅读