批处理脚本在不使用外部软件的情况下压缩文件夹

use*_*778 2 zip batch-file

我有以下结构的文件夹

folder子文件夹(空)子文件夹file1.bat file2.bat file3.bat

如何在不使用winrar或7zip等外部软件的情况下编写批处理文件来压缩上述文件夹的内容?

我尝试了下面的代码.但它会将内容复制到指定的临时文件夹而没有空文件夹,并且在尝试压缩文件夹时,它只会压缩file1和file2并忽略其余内容.

我希望能够在不影响结构的情况下压缩文件夹.

我找不到问题的原因.任何帮助表示赞赏.

set FILETOZIP=D:\OutputZipFiles\TestWorkDemo


set TEMPDIR=D:\OutputZipFiles\TempDir
rmdir %TEMPDIR%
mkdir %TEMPDIR%
xcopy /s %FILETOZIP% %TEMPDIR%

echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs

CScript  _zipIt.vbs  %TEMPDIR%  D:\OutputZipFiles\someArchive.zip

pause
Run Code Online (Sandbox Code Playgroud)

roj*_*ojo 5

正如npocmaka所说,Windows无法通过脚本或拖放将单个空文件夹添加到zip文件中.

但是你激励了我.我决定在JScript中编写一个zip实用程序,只是为了看看我是否可以.为了解决您当前的问题,我添加了一个空文件夹检查.如果遇到空文件夹,此脚本将在名为"(空)"内创建一个新的子文件夹.它或者是,添加一个0字节的文件,或者抛出错误并跳过添加文件夹.

无论如何,如果您想尝试它,请使用.bat扩展名保存此脚本并运行它.当然,它并不像VBscript那么简单,但它有更好的日志记录,错误处理和时序; 它可以压缩单个文件和文件夹.

@if (@a==@b) @end   /* JScript ignores this multiline comment

:: zip.bat file/folder1 [file/folder2 [file/folder3 etc...]] [-o outfile.zip]
:: creates a zip file

@echo off
setlocal enabledelayedexpansion

if "%~1"=="" (
    echo Usage: %~nx0 [-o outfile.zip] "file1 or folder1" ["file2 or folder2"] etc.
    echo If -o is not used, the zip file is named based on the first infile.
    goto :EOF
)

:: convert wildcards to individual filenames
for %%I in (%*) do (
    echo(%%I | findstr "[\*\?]" >NUL && (
        for /f "tokens=*" %%x in ('dir /b %%I') do set "args=!args! "%%~fx""
    ) || set "args=!args! "%%~I""
)

if "!args!" equ "" (
    echo(%* does not exist.
    goto :EOF
)
cscript /nologo /e:Jscript "%~f0" !args!

goto :EOF

:: end of batch portion / begin JScript portion */
var files = [], outfile,
    fso = new ActiveXObject("scripting.filesystemobject"),
    shl = new ActiveXObject("shell.application");

function chr(n) { return String.fromCharCode(n); }

for (var i=0; i<WSH.Arguments.length; i++) {
    if (WSH.Arguments(i).toLowerCase() == '-o') outfile = WSH.Arguments(++i);
    else files.push(WSH.Arguments(i));
}
if (!outfile) try { outfile = files[0].split(/[\/\\]/)[0] + '.zip'; }
catch(e) { outfile = 'archive.zip'; } // Probably never see this, but just in case.

WSH.Echo('Creating ' + outfile);

var zip = fso.CreateTextFile(outfile);
zip.Write("PK" + chr(5) + chr(6));
for (var i=18; i>0; i--) zip.Write(chr(0));
zip.Close()
zip = shl.NameSpace(fso.GetFile(outfile).Path);

for (var i=0; i<files.length; i++) {
    try {
        if (fso.FileExists(files[i])) {
            var file = fso.GetFile(files[i]);
        } else if (fso.FolderExists(files[i])) {
            var file = fso.GetFolder(files[i]);
            if (!shl.NameSpace(file.Path).Items().Count) {
                // Windows can't add an empty folder to a zip file, but
                // it *can* add a folder that contains an empty folder.
                shl.NameSpace(file.Path).NewFolder('(empty)');
            }
        } else {
            throw "Unable to locate " + files[i];
        }
        var folder = shl.NameSpace(file.ParentFolder + '\\'),
        zipThis = folder.ParseName(fso.GetFileName(files[i]));
    }
    catch(e) {
        var output = 'Skipping ' + files[i] + ': ';
        output += (typeof e === 'string') ? e : (
            e.description ? e.description : 'error ' + e.number + ' (unspecified error)'
        );
        WSH.Echo(output);
        files.splice(i--,1);
        continue;
    }
    WSH.StdOut.Write('Compressing ' + fso.GetFileName(file) + '... ');
    zip.CopyHere(zipThis);
    while (zip.Items().Count <= i) {
        WSH.Sleep(50);
    }
    WSH.Echo('Done.  (' + zip.Items().Count + ' of ' + files.length + ')');
}

if (!zip.Items().Count) {
    fso.DeleteFile(fso.GetFile(outfile));
    WSH.Echo('Zip file is empty.  Deleting.');
}
Run Code Online (Sandbox Code Playgroud)

在这里使用JScript优于VBScript的优点是不需要回显_zipIt.vbs.JScript提供了内联评估作为批处理脚本的混合的能力.你掠夺的vbscript有另一个问题,因为它随意调用WScript.Sleep 2000,无论完成复制需要多少时间.如果您要复制大文件,2秒可能不够.如果你复制一些小东西,那就浪费了.