0

我使用 7za 的命令行实用程序混淆了一个 vbs 脚本来压缩超过 7 天的文件。虽然大多数逻辑工作正常,但我能够将单个文件压缩成单个 zip 文件。

当我尝试将所有匹配文件添加到一个 zip 文件时,就会出现问题。下面是代码片段:

strCommand = "7za.exe -mx=9 a " & ObjectFolder & sysDate & ".zip " & strFileName
strRun = objShell.Run(strCommand, 0, True)

现在根据第 2,设置True将确保脚本将等待命令完成执行。但问题是7za立即退出并进入下一个循环,处理下一个文件,因为它试图创建相同的 zip 文件,所以我收到拒绝访问错误。

有人可以帮我解决这个问题吗?

我还在命令提示符下测试了该场景。我所做的是,在单独的提示中同时执行以下 2 个命令:

提示1:C:\7za.exe -mx=9 a test.zip c:\sample1.pdf

提示2:C:\7za.exe -mx=9 a test.zip c:\sample2.pdf

提示 2 导致以下错误:

错误:不支持 test.zip 存档

系统错误:
该进程无法访问该文件,因为它正被另一个进程使用。

这是我在脚本中遇到的相同错误,我需要帮助来解决这个问题。任何指示都会有所帮助!

更新:

借助 John 和 Ansgar 提供的出色指示,我能够解决这个问题!原来是我的脚本中的一个错误!在我的脚本中,我在处理文件进行归档之前检查了该文件是否正在被任何其他进程使用。所以我通过打开文件进行检查,使用:

Set f = objFSO.OpenTextFile(strFile, ForAppending, True)

但是在继续处理同一个文件之前,我没有在脚本中关闭它,因此出现错误:该进程无法访问该文件,因为它正在被另一个进程使用

关闭文件后,一切顺利!

再次感谢我在这里得到的所有大力支持!

为了表示感谢,我将分享整个脚本以供任何人使用。请注意,我不是本文的原作者,我从各种来源收集了它,并对其进行了一些调整以满足我的需要。

存档.vbs

Const ForAppending = 8  ' Constant for file lock check

Dim objFSO, objFolder, objFiles, objShell
Dim file, fileExt, fileName, strCommand, strRun, strFile
Dim SFolder, OFolder, Extension, DaysOld, sDate

'''' SET THESE VARIABLES! ''''
SFolder = "C:\SourceFolder\"      'Folder to look in
OFolder = "C:\OutputFolder\"      'Folder to put archives in
Extension = "pdf"        'Extension of files you want to zip
DaysOld = 1        'Zip files older than this many days
''''''''''''''''''''''''''''''

sDate = DatePart("yyyy",Date) & "-" & Right("0" & DatePart("m",Date), 2) & "-" & Right("0" & DatePart("d",Date), 2)


'Create object for playing with files
Set objFSO = CreateObject("Scripting.FileSystemObject")

'Create shell object for running commands
Set objShell = wscript.createObject("wscript.shell")

'Set folder to look in
Set objFolder = objFSO.GetFolder(SFolder)

'Get files in folder
Set objFiles = objFolder.Files

'Loop through the files
For Each file in objFiles
  fileName = Split(file.Name, ".")
  fileExt = fileName(UBound(fileName))
  'See if it is the type of file we are looking for
  If fileExt = Extension Then
    'See if the file is older than the days chosen above
    If DateDiff("d", file.DateLastModified, Now()) >= DaysOld Then
      strFile = file.Path
      'See if the file is available or in use
        Set f = objFSO.OpenTextFile(strFile, ForAppending, True)
        If Err.Number = 70 Then ' i.e. if file is locked

        Else
        f.close
        strFName = objFSO.GetBaseName(file.name)
        strCommand = "C:\7za.exe -mx=9 a " & OFolder & sDate & ".zip " & strFile

        strRun = objShell.Run(strCommand, 0, True)
        'wscript.echo strCommand  ' un-comment this to check the file(s) being processed
        'file.Delete  ' un-comment this to delete the files after compressing.
        End If
    End If

  End If
Next

'Cleanup
Set objFiles = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
Set objShell = Nothing
wscript.Quit

============================

谢谢

——诺曼 A。

4

2 回答 2

1

不完全符合您的要求,但这是我用于类似任务的批处理脚本,以帮助您解决当前的问题:

ArchiveScriptLog.Bat

::ensure we're in the right directory, then run the script & log the output
cls
pushd "c:\backup scripts"
ArchiveScript.bat > ArchiveScript.log
popd

存档脚本.bat

::Paths (must include the \ on the end).  There must be no space between the equals and the value
::UNC paths are acceptable

Set FolderToBackup=F:\EnterpriseArchitect\Energy\
Set BackupPath=F:\EnterpriseArchitect\!ARCHIVE\
Set RemoteBackupPath=\\ukccojdep01wok\h$\Energy\cciobis01edc\
Set SevenZip=C:\Program Files (x86)\7-Zip\

::Get DATE in yyyymmdd format; done in two lines to make it easy to change the date format
FOR /F "TOKENS=2,3,4 DELIMS=/ " %%A IN ('echo %Date%') DO (SET mm=%%A&SET dd=%%B&SET yyyy=%%C)
SET strDate=%yyyy%%mm%%dd%

::Set the Backup File to be the backup path with the current date & .zip on the end
Set BackupFile=%BackupPath%%strDate%.zip

::create a zip containing the contents of folderToBackup
pushd %SevenZip%
7z a "%BackupFile%" "%FolderToBackup%"
popd

::go to the archive directory & copy all files in there to the remote location (this accounts for previous errors if the network were unavailable)
pushd "%BackupPath%"
move *.zip "%RemoteBackupPath%"
popd

::delete off backups in the remote location which are older than 90 days
pushd "%RemoteBackupPath%"
forfiles /D -90 /M *.zip /C "cmd /c del @file"
popd
于 2012-10-18T22:03:07.463 回答
1

7za您的命令在完成任务之前不应该返回(在我的测试中也没有)。尝试将您的代码更改为以下内容,这样您就可以看到发生了什么:

strCommand = "7za.exe -mx=9 a " & ObjectFolder & sysDate & ".zip " & strFileName
strCommand = "%COMSPEC% /k " & strCommand
strRun = objShell.Run(strCommand, 1, True)

引用文件名也可能是一个好主意:

Function qq(str)
  qq = Chr(34) & str & Chr(34)
End Function

strCommand = "7za.exe -mx=9 a " & qq(ObjectFolder & sysDate & ".zip") & " " _
  & qq(strFileName)
于 2012-10-19T08:04:30.523 回答