我正在尝试将单个目录中的所有文件压缩到另一个文件夹中,作为简单备份程序的一部分。
代码运行正常但没有生成 zip 文件:
$srcdir = "H:\Backup"
$filename = "test.zip"
$destpath = "K:\"
$zip_file = (new-object -com shell.application).namespace($destpath + "\"+ $filename)
$destination = (new-object -com shell.application).namespace($destpath)
$files = Get-ChildItem -Path $srcdir
foreach ($file in $files)
{
$file.FullName;
if ($file.Attributes -cne "Directory")
{
$destination.CopyHere($file, 0x14);
}
}
你知道我哪里做错了吗?
答案1
这在 V2 中有效,在 V3 中也应该有效:
$srcdir = "H:\Backup"
$zipFilename = "test.zip"
$zipFilepath = "K:\"
$zipFile = "$zipFilepath$zipFilename"
#Prepare zip file
if(-not (test-path($zipFile))) {
set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipFile).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipFile)
$files = Get-ChildItem -Path $srcdir | where{! $_.PSIsContainer}
foreach($file in $files) {
$zipPackage.CopyHere($file.FullName)
#using this method, sometimes files can be 'skipped'
#this 'while' loop checks each file is added before moving to the next
while($zipPackage.Items().Item($file.name) -eq $null){
Start-sleep -seconds 1
}
}
答案2
我发现了另外两种方法可以做到这一点,并将它们作为参考:
使用.Net framework 4.5(由@MDMarra 建议):
[Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
[System.AppDomain]::CurrentDomain.GetAssemblies()
$src_folder = "h:\backup"
$destfile = "k:\test.zip"
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includebasedir = $false
[System.IO.Compression.ZipFile]::CreateFromDirectory($src_folder, $destfile, $compressionLevel, $includebasedir)
这在我的 Win7 开发机器上运行良好,可能是实现此目的的最佳方法,但 .Net 4.5 仅在 Windows Server 2008(或更高版本)上受支持,我的部署机器是 Windows Server 2003。
使用命令行 zip 工具:
function create-zip([String] $aDirectory, [String] $aZipfile)
{
[string]$PathToZipExe = "K:\zip.exe";
& $PathToZipExe "-r" $aZipfile $aDirectory;
}
create-zip "h:\Backup\*.*" "K:\test.zip"
我下载了信息压缩包并使用源位置和目标位置作为参数来调用它。
这工作得很好并且设置起来非常简单,但需要外部依赖。