我有以下脚本将文件夹(文件夹中的所有文件)压缩为zip文件:
set-content $zipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
$ZipFile = (new-object -com shell.application).NameSpace($zipFileName)
Get-ChildItem $folder | foreach {$zipFile.CopyHere($_.fullname)}
其中$ folder =“C:\ Test”,$ zipFileName =“C:\ data \ test.zip”为例
如果“C:\ Test”不包含空的子文件夹,它可以正常工作,并且它似乎递归地压缩子文件夹中的所有文件。我真的很喜欢上面简单的线条脚本。例如:
C:\Test
file1.dat
file2.dat
Test-Sub
File21.bat
....
但是,我在一个案例中遇到错误。我发现如果有任何空文件夹,例如“C:\ Test \ EmptySub”,
C:\Test
file1.dat
file2.dat
Test-Sub
File21.bat
....
EmptySub
AnotherSub
file31.sp1
...
该脚本将生成错误。我尝试了以下脚本:
Get-ChildItem $files -Recurse | foreach { if (!$_.PSIsContainer)
{$zipFile.CopyHere($_.fullname)}}
这不能按预期工作。它只是跳过所有子文件夹。不确定是否有可用于跳过所有空子文件夹的过滤器或子句?
已更新:根据建议,我试了一下。我的问题还没有解决。这是我的问题的更新。首先,我更新了上面的脚本,以显示如何创建$ zipFile对象。其次,我有建议的代码:
Get-ChildItem $files | ? {-not ($_.PSIsContainer -eq $True -and
$_.GetFiles().Count -eq 0) } | % {$zipfile.CopyHere($_.fullname)}
我在WindowsXP上尝试了以上更新,它可以正常使用空子文件夹。但是,相同的代码在Windows 2003 Server中不起作用。以下是错误消息:
[窗口标题] 压缩(压缩)文件夹错误
[内容] 找不到文件或没有读取权限。
[确定]
不确定此类型的PK对象是否可以在Windows 2003服务器中运行,或者该对象是否还有其他设置。
答案 0 :(得分:3)
您可以通过测试get-childitem的空返回来检测空目录。例如,这将返回空目录列表
dir | where{$_.PSIsContainer -and -not (gci $_)}
虽然在你的情况下,你想要反过来:
Get-ChildItem $files | where{-not ($_.PSIsContainer -and -not (gci $_))} | foreach {$zipfile.CopyHere($_.fullname)}}
答案 1 :(得分:2)
您的代码以递归方式工作,即您获得任何类型的子项(包括文件夹)。如果您打算排除空文件夹,则应过滤它们:
试试这个衬垫:
gci $folder |` ? {-not ($_.PSIsContainer -eq $True -and $_.GetFiles().Count -eq 0) } |` % {$zipfile.CopyHere($_.fullname)}
答案 2 :(得分:1)
这是我为zip文件创建的函数。您收到读取错误的原因是因为.CopyHere是异步复制过程,因此我的脚本会在继续下一个要压缩的文件之前验证zip文件中是否存在该文件:
function Out-ZipFile ([string]$path)
{
try
{
$files = $input
if ($path.StartsWith(".\")) { $path=$path.replace(".\","$($pwd)\") }
if (-not $path.Contains("\")) { $path="$($pwd)\$($path)" }
if (-not $path.EndsWith('.zip')) {$path += '.zip'}
if (-not (test-path $path)) {
set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
}
$ZipFile = (new-object -com shell.application).NameSpace($path)
$files | % {
$FileName = $_.name
"Adding $FileName to $path";
$ZipFile.CopyHere($_.fullname);
While (($ZipFile.Items() | where { $_.Name -like $FileName }).Size -lt 1) { Start-Sleep -m 100 };
}
}
catch
{
write-output "Error Encountered: `n$_"
return $_
throw
}
}