Powershell Compress-Archive:进程无法访问该文件,因为它正由另一个进程使用

时间:2017-11-13 10:38:09

标签: powershell

我是PowerShell的新手。

我想压缩路径(内部运行服务窗口)。

当服务停止时,它运行正常,当服务运行时,我有例外:

  

该进程无法访问该文件,因为该文件正被另一个文件使用   过程

然而,当我用7-zip拉链时,我没有任何例外。

我的命令非常简单:

Compress-Archive [PATH] -CompressionLevel Optimal -DestinationPath("[DEST_PATH]") -Force

您是否有任何想法在没有此例外的情况下执行任务?

3 个答案:

答案 0 :(得分:1)

访问另一个进程正在使用的文件的好方法是使用Volume Shadow Copy Service创建快照。

要做到这一点,可以简单地使用PowerShells WMI Cmdlet:

$Path = "C:/my/used/folder"
$directoryRoot = [System.IO.Directory]::GetDirectoryRoot($Path).ToString()

$shadow = (Get-WmiObject -List Win32_ShadowCopy).Create($directoryRoot, "ClientAccessible")
$shadowCopy = Get-WmiObject Win32_ShadowCopy | ? { $_.ID -eq $shadow.ShadowID }
$snapshotPath = $shadowCopy.DeviceObject + "\" + $Path.Replace($directoryRoot, "")

现在,您可以使用$snapshotPath -Path作为Compress-Archive来电。

此方法还可用于使用符号链接创建备份。 从那里,您可以使用链接的文件夹来复制备份的文件,或者在没有这些Access异常的情况下压缩它们。

我在这个要点中创建了一个类似的函数和一个小的Cmdlet:Backup.ps1

答案 1 :(得分:0)

Copy-Item允许您访问另一个进程中正在使用的文件。

这是我最终在代码中使用的解决方案:

{{1}}

想法是,您通过管道传递所有复制的项目,而不必在压缩之前先将它们复制到特定的目标。

我喜欢压缩文件夹的内容而不是文件夹本身,因此我在最后一行压缩之前使用Get-ChildItem。

子文件夹已包含在内。无需在第一行中使用-recurse

答案 2 :(得分:0)

有一个类似的要求,即只需将很少的扩展名添加到zip中。 通过这种方法,我们可以将所有文件(包括锁定文件)复制到临时位置>压缩文件,然后删除日志

这是一个漫长的过程,但让我高兴了!

$filedate = Get-Date -Format yyyyMddhhmmss
$zipfile = 'C:\Logs\logfiles'+ $filedate +'.zip'

New-Item -Path "c:\" -Name "Logs" -ItemType "directory" -ErrorAction SilentlyContinue

Robocopy "<Log Location>" "C:\CRLogs\" *.txt *.csv *.log /s
Get-ChildItem -Path "C:\Logs\" -Recurse | Compress-Archive -DestinationPath $zipfile -Force -ErrorAction Continue
Remove-Item -Path "C:\Logs\" -Exclude *.zip -Recurse -Force