我正在创建一个夜间数据库模式文件,并希望将每晚创建的所有文件(每个数据库一个文件)放入一个文件夹并压缩该文件夹。我有一个创建模式的 PowerShell 脚本。仅创建数据库的脚本,然后将所有文件添加到新文件夹中。问题在于这个过程的压缩部分。
是否有人知道这是否可以通过预安装的处理文件夹压缩的 Windows 实用程序来完成?
如果可能,最好使用该实用程序而不是 7zip 之类的工具(我不想在每个客户的服务器上安装 7zip,如果我问他们可能需要几年的时间来完成)。
我正在创建一个夜间数据库模式文件,并希望将每晚创建的所有文件(每个数据库一个文件)放入一个文件夹并压缩该文件夹。我有一个创建模式的 PowerShell 脚本。仅创建数据库的脚本,然后将所有文件添加到新文件夹中。问题在于这个过程的压缩部分。
是否有人知道这是否可以通过预安装的处理文件夹压缩的 Windows 实用程序来完成?
如果可能,最好使用该实用程序而不是 7zip 之类的工具(我不想在每个客户的服务器上安装 7zip,如果我问他们可能需要几年的时间来完成)。
采用最新 .NET 4.5 框架的原生方式,但完全没有功能:
创建:
Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::CreateFromDirectory("c:\your\directory\to\compress", "yourfile.zip") ;
萃取:
Add-Type -Assembly "System.IO.Compression.FileSystem" ;
[System.IO.Compression.ZipFile]::ExtractToDirectory("yourfile.zip", "c:\your\destination") ;
如前所述,完全没有功能,所以不要指望覆盖标志。
下面是一些不依赖扩展的与 zip 相关的函数:Compress Files with Windows PowerShell。
您可能感兴趣的主要功能是:
function Add-Zip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}
用法:
dir c:\demo\files\*.* -Recurse | Add-Zip c:\demo\myzip.zip
有一个警告:如果路径不是绝对的,则shell.application
对象的NameSpace()
函数无法打开 zip 文件进行写入。因此,如果您将相对路径传递给Add-Zip
,它将失败并返回 null 错误,因此 zip 文件的路径必须是绝对路径。
或者你可以$zipfilename = resolve-path $zipfilename
在函数的开头添加一个。
从 PowersShell 5 开始,有一个Compress-Archive cmdlet 可以开箱即用地完成任务。
这将 .\in 内容压缩到 .\out.zip 并使用 System.IO.Packaging.ZipPackage 按照此处的示例
$zipArchive = $pwd.path + "\out.zip"
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
$in = gci .\in | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files) {
$partName=New-Object System.Uri($file, [System.UriKind]"Relative")
$part=$ZipPackage.CreatePart($partName, "application/zip", [System.IO.Packaging.CompressionOption]"Maximum")
$bytes=[System.IO.File]::ReadAllBytes($file)
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$ZipPackage.Close()
使用voithos在powershell中压缩文件的答案,只是Add-Zip功能出现了一个问题,如果文件在那段时间内无法完全压缩,则Start-sleep -milliseconds 500会导致问题->下一个开始在它完成之前导致错误和一些文件没有被压缩。
所以在玩了一会儿之后,首先尝试让一个计数器检查 $zipPackage.Items() 的计数,并且只有在项目计数增加后才继续(这不起作用,因为在某些情况下它会返回 0不应该)我发现如果包仍在压缩/复制文件,它将返回 0(我认为,哈哈)。添加了一个简单的 while 循环,其中包含 start-sleep,等待 zipPackage.Items().count 在继续之前为非零值,这似乎解决了问题。
function Add-Zip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
do
{
Start-sleep -milliseconds 250
}
while ($zipPackage.Items().count -eq 0)
}
}
使用 PowerShell 3.0 版:
Copy-ToZip -File ".\blah" -ZipFile ".\blah.zip" -Force
希望这可以帮助。