如何防止 Windows 每次尝试复制以非法字符命名的文件时抛出错误?

如何防止 Windows 每次尝试复制以非法字符命名的文件时抛出错误?

我正在解压一个中等大小的 ZIP 文件,其中包含数千个名称不同的小文件。其中一些文件的名称包含非法字符,如“:”。这导致 Windows 在尝试解压这些文件并将其复制到目标文件夹时出现问题。

它抛出了Error 0x80070057。网上的一些资料声称这是由于磁盘空间不足造成的,但就我的情况而言,这绝对不是事实。此错误很可能是由于文件名称中包含非法字符,因为其他文件复制时没有问题。

然后 Windows 要求我Try AgainSkip,一旦我选择重试,它就会用“_”替换任何非法字符,从而很好地解决问题。

我的问题是如何防止 Windows 询问我数千次?我尝试选中复选框Do this for all current items,但没有效果。

这个问题与这个。一是因为我没有使用 7Zip,而是使用 Windows 内置的提取程序。二是因为那个问题是关于解决名称冲突,而这个问题是关于从文件名中删除非法字符。

答案1

.NetSystem.IO.Compression 命名空间。它们提供各种方法,让您对创建、修改和提取有更高级别的控制。

为了在提取过程中将任何非法文件名转换为合法文件名,使用的方法/属性将是:


编辑:PowerShell 代码用于纠正提取过程中的非法文件名

由于您找到了适合您的 Python 解决方案,因此我花了一些时间尝试这些类,因为它们对我来说很新。但为了满足好奇和未来的读者,这里是直接的 PowerShell/.net 代码。

此代码将打开一个 .zip 文件作为压缩档案并替换每个名称/全名中的任何非法字符Zip存档条目_在提取之前使用下划线( )字符。

此处的输入是硬编码的,以保持对文件操作的关注,但代码可以作为功能或上下文菜单项的基础。

###   User Input   ###
$ZipPath        = 'C:\Users\Whoever\Wherever\Illegal.zip'   ###   Path to .zip file
$ExtractPath    = 'C:\Users\Whoever\NonExisting'            ###   Path of target directory

###   Load required assemblies
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem

###   Construct regex character class to match illegal characters
$IllegalChars   = '[{0}]' -f ( -join [IO.Path]::GetInvalidFileNameChars().ForEach{[Regex]::Escape($_)})

###   Create target directory if it doesn't exist
If (!(Test-Path $ExtractPath))
{
    mkdir $ExtractPath -Force | out-null
}

###   Ensure ExtractPath is fully-qualified for subsequent operations
$ExtractPath    = [IO.Path]::GetFullPath($ExtractPath)

$Archive        = [IO.Compression.ZipFile]::OpenRead($ZipPath)

$Archive.Entries | ForEach{
    If ($_.Name -eq $_.FullName)   ###   no subdirectory
    {
        [IO.Compression.ZipFileExtensions]::ExtractToFile($_, (Join-Path $ExtractPath ($_.Name -replace ($IllegalChars,'_'))))
    }
    Else                           ###   subdirectory 
    {
        $ChildPath   = $_.FullName.Split('/') -replace ($IllegalChars,'_') -join [io.Path]::DirectorySeparatorChar
        $subFolder   = Split-Path $ChildPath
        If (!(Test-Path $subFolder))
        {
            mkdir $subFolder -Force | out-null
        }
        [IO.Compression.ZipFileExtensions]::ExtractToFile($_, (Join-Path $ExtractPath $ChildPath))
    }
}

相关内容