【问题标题】:batch script to zip a folder without using external softwares在不使用外部软件的情况下压缩文件夹的批处理脚本
【发布时间】:2015-02-01 02:40:11
【问题描述】:

我有以下结构的文件夹

文件夹 子文件夹(空) 子文件夹 文件1.bat 文件2.bat 文件3.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

【问题讨论】:

    标签: batch-file zip


    【解决方案1】:

    作为npocmaka said,Windows 无法通过脚本或拖放将单个空文件夹添加到 zip 文件中。

    但你启发了我。我决定用 JScript 编写一个 zip 实用程序,只是为了看看我是否可以。为了解决您当前的问题,我添加了对空文件夹的检查。如果遇到空文件夹,此脚本将在其中创建一个名为“(empty)”的新子文件夹。要么,添加一个 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.');
    }
    

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

    【讨论】:

    • 感谢您的帮助。此代码似乎提供了所需的输出
    【解决方案2】:

    Shell.Application 1 级空文件夹总是被跳过。您可以通过选择一堆文件(包括空文件夹)自己测试,并尝试通过 Windows 资源管理器将它们粘贴到一个 zip 文件中(这实际上是 shell 使用的应用程序)。作为解决方法,您可以将所需的文件夹复制到另一个空文件夹中并压缩新文件夹。然后,您将拥有应该压缩的 2 级空目录。

    【讨论】:

      猜你喜欢
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      相关资源
      最近更新 更多