批处理脚本来压缩文件夹,而无需使用外部软件 [英] batch script to zip a folder without using external softwares

查看:347
本文介绍了批处理脚本来压缩文件夹,而无需使用外部软件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下结构的文件夹

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

我如何去写一个批处理文件来压缩上述文件夹的内容,而无需使用外部软件一样WinRar或7zip的?

我试过低于code。但是,试图压缩它只会压缩文件1和file2文件夹和忽略的内容,其余的时候会复制内容到指定的临时文件夹没有空文件夹和

我希望能够压缩的文件夹,因为它是在不影响结构。

我无法找到问题的原因。任何帮助是AP preciated。

 设置FILETOZIP = D:\\ OutputZipFiles \\ TestWorkDemo
设置TEMPDIR = D:\\ OutputZipFiles \\ TEMPDIR
命令rmdir%TEMPDIR%
MKDIR%TEMPDIR%
XCOPY / S%FILETOZIP%%TEMPDIR%呼应设置objArgs = WScript.Arguments> _zipIt.vbs
回声InputFolder = objArgs(0)>> _zipIt.vbs
呼应的ZipFile = objArgs(1)>> _zipIt.vbs
回声的CreateObject(Scripting.FileSystemObject的)CreateTextFile(ZipFile的,真).WRITEPK^&放大器。 CHR(5)^&安培; CHR(6)^&安培;字符串(18 vbNullChar)GT;> _zipIt.vbs
回声设置objShell =的CreateObject(Shell.Application)>> _zipIt.vbs
呼应设置源= objShell.NameSpace(InputFolder).Items>> _zipIt.vbs
回声objShell.NameSpace(的ZipFile).CopyHere(源​​)>> _zipIt.vbs
回声wScript.Sleep 2000>> _zipIt.vbs在CScript _zipIt.vbs%TEMPDIR%D:\\ OutputZipFiles \\ someArchive.zip暂停


解决方案

npocmaka说,Windows无法添加一个空文件夹到一个ZIP文件或者通过脚本或拖坠。

但你启发了我。我决定写在JScript中的zip工具,只是为了看看是否我可以。为了解决当前的问题,我增加了对空文件夹的支票。如果遇到一个空文件夹,该脚本将创建中调用(空)的新的子文件夹。这是要么,加个0字节的文件,或抛出一个错误,并跳过添加的文件夹。

无论如何,如果你想尝试一下,保存这个脚本以.bat扩展名并运行它。当然,它不是你的VBscript的那样简单,但它有更好的日志记录,错误处理和时间;它可以压缩从个人文件以及文件夹。

  @if(@a == @二)@end / * JScript中忽略这个多行注释:: zip.bat文件/文件夹1 [文件/文件夹2 [文件/ folder3等...]] [-o outfile.zip]
::创建一个zip文件关闭@echo
SETLOCAL enabledelayedexpansion如果%〜1==(
    回声用法:%〜NX0 [-o outfile.zip]文件1或文件夹1[文件2或文件夹2]等。
    回声如果没有使用-o,zip文件基础上的第一个INFILE而得名。
    GOTO:EOF
)::转换通配符名个人
为%%我在(%*)做(
    回声(%% I | FINDSTR[\\ * \\?]> NUL&放大器;及(
        FOR / F令牌= *%%倍In('DIR / B %% I')不设置ARGS =!ARGS!%%〜FX
    )||集ARGS =!ARGS!%%〜I
)如果!ARGS! EQU(
    回声(%*不存在。
    GOTO:EOF

CSCRIPT / NOLOGO / E:JScript中,%〜F0ARGS!GOTO:EOF::批部分的结束/开始JScript的部分* /
var中的文件= [],outfile中,
    FSO =新的ActiveXObject(Scripting.FileSystemObject的),
    SHL =新的ActiveXObject(shell.application);功能CHR(N){返回String.fromChar code(N); }对于(VAR I = 0; I< WSH.Arguments.length;我++){
    如果(WSH.Arguments(I).toLowerCase()=='-o')= outfile的WSH.Arguments(++一);
    其他files.push(WSH.Arguments(I));
}
如果(!OUTFILE)尽量{OUTFILE =文件[0] .split(/ [\\ / \\\\] /)[0] +'的.zip'; }
赶上(E){OUTFILE ='archive.zip'; } //大概永远也看不到这一点,但以防万一。WSH.Echo('创建'+ OUTFILE);VAR邮编= fso.CreateTextFile(OUTFILE);
zip.Write(PK+ CHR(5)+ CHR(6));
对于(VAR我= 18; I> 0;我 - )zip.Write(CHR(0));
zip.Close()
邮编= shl.NameSpace(fso.GetFile(OUTFILE)。路径);对于(VAR I = 0; I< files.length;我++){
    尝试{
        如果(fso.FileExists(文件[I])){
            var文件= fso.GetFile(文件[I]);
        }否则如果(fso.FolderExists(文件[I])){
            var文件= fso.GetFolder(文件[I]);
            如果(!shl.NameSpace(file.Path).Items()。计数){
                // Windows不能添加一个空文件夹到一个zip文件,但
                //它可以* *添加包含一个空文件夹的文件夹。
                shl.NameSpace(file.Path).NewFolder('(空)');
            }
        }其他{
            抛出找不到+文件[I]
        }
        VAR文件夹= shl.NameSpace(file.ParentFolder +'\\\\'),
        zipThis = folder.ParseName(fso.GetFileName(文件[I]));
    }
    赶上(E){
        无功输出='跳过'+文件[I] +':';
        输出+ =(typeof运算è==='串')? E:(
            e.description? e.description:'错误'+ e.number +'(未指定错误)
        );
        WSH.Echo(输出);
        files.splice(ⅰ - ,1);
        继续;
    }
    WSH.StdOut.Write('的COM pressing'+ fso.GetFileName(文件)+'...');
    zip.CopyHere(zipThis);
    而(zip.Items()计数< = 1){
        WSH.Sleep(50);
    }
    WSH.Echo(完成('+ zip.Items()计数+'的'+ files.length +')');
}如果(!zip.Items()。计数){
    fso.DeleteFile(fso.GetFile(OUTFILE));
    WSH.Echo('Zip文件是空删除。');
}

使用JScript在VBScript中的优势在这里是没有必要呼应出 _zipIt.vbs 。 JScript中能提供被内嵌评价为批处理脚本的混合动力的能力。将VBScript你掠夺了另一个问题,因为它任意调用 WScript.Sleep 2000 ,无论需要多少时间来完成复制。如果你正在复制大文件2秒可能没有足够的时间。而且它是浪费的,如果你复制小东西。

I have folder with the following structure

folder subfolder(empty) subfolder file1.bat file2.bat file3.bat

How do I go about writing a batch file to zip the contents of the above folder without using external softwares like winrar or 7zip?

I tried the below code. But it would copy the contents to the specified temp folder without the empty folder and when attempting to zip the folder it would only zip file1 and file2 and ignore rest of the contents.

I would like to be able to zip the folder as it is without affecting the structure.

I could not find the reason for the issue. Any help is appreciated.

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

解决方案

As npocmaka said, Windows can't add a single empty folder to a zip file either through scripting or drag-and-dropping.

But you've inspired me. I decided to write a zip utility in JScript, just to see whether I could. To address your current problem, I added a check for empty folders. If an empty folder is encountered, this script will create a new child folder within called "(empty)". It was either that, add a 0-byte file, or throw an error and skip adding the folder.

Anyway, if you'd like to try it, save this script with a .bat extension and run it. Granted, it's not as simple as your VBscript, but it's got better logging, error handling, and timing; and it can zip individual files as well as folders.

@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.');
}

The advantage of using JScript over VBScript here is that there's no need to echo out to _zipIt.vbs. JScript affords the ability to be evaluated inline as a hybrid of a batch script. Your vbscript you plundered has another issue, in that it arbitrarily calls WScript.Sleep 2000, regardless of how much time is needed to complete the copy. If you're copying large files, 2 seconds might not be enough time. And it's wasteful if you're copying something small.

这篇关于批处理脚本来压缩文件夹,而无需使用外部软件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆