我COM preSS(/ ZIP)和uncom preSS(/解压缩)文件和批处理文件的文件夹,而无需使用任何外部工具如何? [英] How can I compress (/ zip ) and uncompress (/ unzip ) files and folders with batch file without using any external tools?

查看:239
本文介绍了我COM preSS(/ ZIP)和uncom preSS(/解压缩)文件和批处理文件的文件夹,而无需使用任何外部工具如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道类似的问题在这里被问了很多,但我并不完全满意答案 (甚至与题)。

主要目标是兼容性 - 它应该是适用于最广泛的Windows机器(包括XP,Vista中,Win2003的 - 它们共同仍持有约20%的Windows共享)可能的范围和生产 文件应该是可用在UNIX / Mac机(因此,标准的归档/ COM pression格式为preferable)。

什么选项有:

  1. 创建一个批处理实现了一些压缩算法。显然,这 是可能的 - 但只有单一的文件,并使用CERTUTIL的 二值化处理(有的机器没有CERTUTIL默认 而不可能被在WinXP家庭版)
  2. 安装
  3. 使用 shell.application <一>通过WSH.The最好的选择,根据/ 以me.It允许荏苒整个目录,并在每个可用 窗机
  4. Makecab - 尽管它的COM pression不是那么便携的 可在每个窗口machine.Some像7zip的外部程序 能够提取.CAB内容,但是这将是不那么 文件需要在Unix / Mac.And同时使用时方便 COM pressing一个文件是pretty的直白,preserving 目录结构需要多一点点的努力。
  5. 在使用.NET Framework - 不是那么好option.Form .NET 2.0有 GZipStream < /一>,但它允许COM $ P $只是单个文件pssion。 。净 4.5有拉链的功能,但它不支持Vista和XP。而更 - .NET默认情况下不会在XP和Win2003的安装,但 因为它极有可能有.NET 2.0先进的4.0这是一个 相当opion。
  6. 在PowerShell的 - 因为它依赖于.NET有相同的capabilities.It的 默认情况下未在XP,2003和Vista的安装,所以我会跳过它。
解决方案

和这里的答案(S):

1.使用纯批处理脚本压缩/解压缩文件。

这是可能的感谢Frank西湖的 ZIP.CMD 和的UNZIP.CMD 它要求 FSUTIL CERTUTIL 。对于Win2003的和WinXP这将需要 2003管理工具包这将安装 CERTUTIL 。要小心,因为ZIP.CMD语法落后:

  ZIP.CMD destination.zip source.file
 

和它只能压缩单个文件。

2,采用Shell.Application

我花了一些时间来创建该拉链共同使用一个单一的JScript /批混合脚本/解压缩的文件和目录(加上一些更多的功能)。<一个href="https://github.com/npocmaka/batch.scripts/blob/master/hybrids/jscript/zipjs.bat">Here's它的链接 (它变得太大,张贴在回答)。 可直接使用的蝙蝠扩展,不会产生任何临时文件。 我希望帮助信息是如何能够用足够的描述。

一些例子:

一个压缩的

  //解压内容的zip给予folder.content会不会preserved(-keep无).Destination将不会被覆盖(-force无)
拨打zipjs.bat解压 - 源C:\ MYDIR \ myZip.zip -destination C:\ MYDIR -keep没有-force无

//列出一个zip文件的内容,并完整路径将被打印(-flat是)
拨打zipjs.bat名单 - 源C:\ myZip.zip \ inZipDir -flat是

//列出一个zip文件的内容和内容将列表作为树(-flat无)
拨打zipjs.bat名单 - 源C:\ myZip.zip -flat没有

以字节为单位//输出uncom pressed大小
zipjs.bat的getSize -source C:\ myZip.zip

//拉链文件夹的内容,而文件夹本身
拨打zipjs.bat zipDirItems  - 源C:\ MYDIR \ -destination C:\ MyZip.zip -keep是-force没有

//拉链的文件或文件夹(使用文件夹itslelf)
拨打zipjs.bat zipItem  - 源C:\ MYDIR \ MYFILE.TXT -destination C:\ MyZip.zip -keep是-force没有

//解压的压缩与给定的路径里面只有一部分
拨打zipjs.bat unZipItem  - 源C:\ MYDIR \ myZip.zip \ InzipDir \ InzipFile -destination C:\ OtherDir -keep没有-force是
拨打zipjs.bat unZipItem  - 源C:\ MYDIR \ myZip.zip \ InzipDir -destination C:\ OtherDir

//添加内容到一个zip文件
拨打zipjs.bat addToZip  - 源C:\ SOME_FILE -destination C:\ MYDIR \ myZip.zip \ InzipDir -keep没有
拨打zipjs.bat addToZip  - 源C:\ SOME_FILE -destination C:\ MYDIR \ myZip.zip
 

荏苒中的一些已知问题:

  • 如果有没有系统驱动器(通常是C :)脚本可能会产生各种错误上有足够的空间,最常见的脚本halts.This是由于的 Shell.Application 的主动使用的% TEMP%文件夹COM preSS / DECOM preSS的数据。
  • 文件夹和文件包含在其名称UNI code符号不能被Shell.Application对象来处理。
  • 最大支持生成的压缩文件的大小约为8GB在Vista和上面和周围2GB的XP / 2003

如果错误信息弹出,并停止执行,并通知了可能reasons.At那一刻我没有办法检测出里面弹出的文本,并给出失败的确切原因脚本检测。

3。 Makecab

的COM pressing一个文件很容易 - makecab file.txt的file.cab。最终的 MaxCabinetSize 可以增加。 COM pressing文件夹需要使用 DestinationDir 指令(相对路径)为每个(子)目录中的文件。 下面的脚本:

 ; @回声关闭

;;;;;该批次部分REM开始;;;;;
;如果%〜2EQU(
;回声无效arguments.For帮助使用:
;回声%〜NX0 /小时
;)
;对于%%一个在(/ H /帮助-h -help)做(
;如果%〜1EQU%%〜一(
;回声COM pressing目录cab文件
;回声%〜NX0目录CABFILE
;呼应uncom preSS使用:
;回声EXPAND CABFILE -F:*。
; )
; )
;
;设置dir_to_cab =%〜F1
;
;设置path_to_dir =%〜PN1
;设置DIR_NAME =%〜N1
;设置drive_of_dir =%〜D1
;集cab_file =%〜2
;
;如果不存在%dir_to_cab%\(
;回声没有通过有效的目录
;退出/ B 1
;)

;
;破发&GT;%TMP%\ makecab.dir.ddf
;
; SETLOCAL enableDelayedExpansion
;针对/ D / R%dir_to_cab%%%一中(*)做(
;
;设置_dir = %%〜PNA
;设置DESTDIR =%DIR_NAME%_目录:%!path_to_dir%=
; (回波(。设置DestinationDir = DESTDIR&GT;!&GT;%TMP%\ makecab.dir.ddf)
;对于%%#中(%%一个\ *)做(
; (回声(%% 382 4#/inf=no>>"%tmp%\makecab.dir.ddf)
; )
;)
;!(回声(。设置DestinationDir = DIR_NAME&GT;!&GT;%TMP%\ makecab.dir.ddf)
;对于%%#中(%〜F1 \ *)做(
;
; (回声(%% 382 4#/inf=no>>"%tmp%\makecab.dir.ddf)
; )

; makecab / F%〜F0/ F%TMP%\ makecab.dir.ddf/ D DiskDirectory1 =%CD%/ D CabinetNameTemplate =%cab_file%的.cab
; DEL / Q / F%TMP%\ makecab.dir.ddf
;出口/ B%ERRORLEVEL%

;;
;;;;该批次部分REM结束;;;;;

;;;;指令部分;;;;;
;;
。新内阁
.SET GenerateInf = OFF
。设置柜= ON
。设置的COM preSS = ON
。设置UniqueFiles = ON
。设置MaxDiskSize = 1215751680;

.SET RptFileName = NUL
.SET InfFileName = NUL

.SET MAXERRORS = 1
;;
;;;;的指令部分结束;;;;;
 

有关DECOM pression 展开CABFILE -F:* 可在Unix中的cabextract 7zip的都可以使用。

4。 .NET和GZipStream

我preferred一个Jscript.net,因为它允许一个整洁的杂交.BAT(无毒输出,也没有临时文件).Jscript不允许传递对象的引用的函数,所以我发现的唯一途径使它的工作是通过读取/按字节写入文件的字节(所以我想这不是最快的方法 - 如何缓冲读取/写入可以做到的)同样只能与单一的文件中使用

  @if(@X)==(@ Y)@end / * JScript的评论
关闭@echo
SETLOCAL

FOR / F令牌= * delims =%% V IN('DIR / B / S / A:-d / O:-n的%SystemRoot%\ Microsoft.NET \框架\ *器jsc.exe')办(
   集JSC = %% V
)

如果不存在%〜n0.exe(
    %JSC%/ NOLOGO /out:"%~n0.exe%〜dpsfnx0
)

 %〜n0.exe%*

ENDLOCAL和放大器;退出/ B%ERRORLEVEL%


* /


导入系统;
进口System.Collections.Generic;
进口System.IO;
进口System.IO.Com pression;



    功能的COM pressFile(源,目的地){
        VAR的SourceFile = File.OpenRead(源);
        VAR destinationFile = File.Create(目标);
        无功输出=新GZipStream(destinationFile,COM pressionMode.Com preSS);
        Console.WriteLine(的COM pressing {0} {1},sourceFile.Name,destinationFile.Name,假);
        变种byteR = sourceFile.ReadByte();
        而(byteR!=  -  1){
            output.WriteByte(byteR);
            byteR = sourceFile.ReadByte();
        }
        sourceFile.Close();
        output.Flush();
        output.Close();
        destinationFile.Close();
    }

    功能Uncom pressFile(源,目的地){
        VAR的SourceFile = File.OpenRead(源);
        VAR destinationFile = File.Create(目标);

        VAR输入=新GZipStream(的资源文件,
            COM pressionMode.Decom preSS,假);
        Console.WriteLine(DECOM pressing {0} {1},sourceFile.Name,
                destinationFile.Name);

        变种byteR = input.ReadByte();
        而(byteR!== -1){
            destinationFile.WriteByte(byteR);
            byteR = input.ReadByte();
        }
        destinationFile.Close();
        input.Close();


    }

VAR参数:字符串[] = Environment.GetCommandLineArgs();

    功能printHelp(){
        Console.WriteLine(的COM preSS和uncom preSS gzip压缩文件:);
        Console.WriteLine(的COM preSS:);
        Console.WriteLine(参数[0] +-c源目标);
        Console.WriteLine(Uncom preSS:);
        Console.WriteLine(参数[0] +-u源目标);


    }

如果(的arguments.length!= 4){
    Console.WriteLine(参​​数错误);
    printHelp();
    Environment.Exit(1);
}

开关(参数[1]){
    案-c:

        玉米pressFile(参数[2],参数[3]);
        打破;
    案-u:
        Uncom pressFile(参数[2],参数[3]);
        打破;
    默认:
        Console.WriteLine(参​​数错误);
        printHelp();
        Environment.Exit(1);
}
 

I know the similar question were asked here a lot , but I'm not completely satisfied with the answers (and even with the questions).

The main goal is compatibility - it should be applicable to widest possible range of windows machines (including XP,Vista,Win2003 - which together still holds around 20% of windows share ) and produced files should be usable on Unix/Mac machines (so standard archiving/compression formats are preferable).

What the options are :

  1. Creating a batch that implements some zip algorithm. Apparently this is possible - but only with single files and using CERTUTIL for binary processing (some machines does not have CERTUTIL by default and is not possible to be installed on WinXP Home Edition)
  2. Using shell.application through WSH.The best option according to me.It allows zipping whole directories and is usable on every windows machine
  3. Makecab - despite its compression is not so portable its available on every windows machine.Some external programs like 7zip are capable to extract .CAB content ,but it will be not so convenient when files need to be used on Unix/Mac.And while compressing a single file is pretty straightforward , preserving directory structure requires a little bit more effort.
  4. Using .NET Framework - not so good option.Form .NET 2.0 there is GZipStream but it allows compression only of single files. .NET 4.5 has Zip capabilities but it's not supported on Vista and XP .And even more - .NET is not installed by default on XP and Win2003 , but as it is highly probable to have .NET 2.0 up-to 4.0 it's a considerable opion.
  5. Powershell - as it relies on .NET it has same capabilities.It's not installed by default on XP,2003 and Vista so I'll skip it.

解决方案

And here are the answer(s):

1.Using "pure" batch script to zip/unzip file.

It's possible thanks to Frank Westlake's ZIP.CMD and UNZIP.CMD it requires FSUTIL and CERTUTIL .For Win2003 and WinXP it will require 2003 Admin Tool Pack which will install CERTUTIL. Be careful as ZIP.CMD syntax is backward :

ZIP.CMD destination.zip source.file

And it can zip only single files.

2.Using Shell.Application

I've spent some time to create a single jscript/batch hybrid script for common usage that zips/unzips files and directories (plus few more features).Here's a link to it (it became too big to post in the answer). Can be used directly with its .bat extension and does not create any temp files. I hope the help message is descriptive enough of how it can be used.

Some examples:

// unzip content of a zip to given folder.content of the zip will be not preserved (-keep no).Destination will be not overwritten (-force no)
call zipjs.bat unzip -source C:\myDir\myZip.zip -destination C:\MyDir -keep no -force no

// lists content of a zip file and full paths will be printed (-flat yes)
call zipjs.bat list -source C:\myZip.zip\inZipDir -flat yes

// lists content of a zip file and the content will be list as a tree (-flat no)
call zipjs.bat list -source C:\myZip.zip -flat no

// prints uncompressed size in bytes
zipjs.bat getSize -source C:\myZip.zip

// zips content of folder without the folder itself
call zipjs.bat zipDirItems -source C:\myDir\ -destination C:\MyZip.zip -keep yes -force no

// zips file or a folder (with the folder itslelf)
call zipjs.bat zipItem -source C:\myDir\myFile.txt -destination C:\MyZip.zip -keep yes -force no

// unzips only part of the zip with given path inside
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir\InzipFile -destination C:\OtherDir -keep no -force yes
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir -destination C:\OtherDir 

// adds content to a zip file
call zipjs.bat addToZip -source C:\some_file -destination C:\myDir\myZip.zip\InzipDir -keep no
call zipjs.bat addToZip -source  C:\some_file -destination C:\myDir\myZip.zip

Some known issues during zipping:

  • if there's not enough space on the system drive (usually C:) the script could produce various errors , most often the script halts.This is due to Shell.Application actively uses %TEMP% folder to compress/decompress the data.
  • Folders and files that contain unicode symbols in their names cannot be handled by Shell.Application object.
  • Max supported size of produced zip files is around 8gb in Vista and above and around 2gb in XP/2003

The script detects if error message pops-up and stops the execution and informs for the possible reasons.At the moment I have no way to detect the text inside the pop-up and give the exact reason for the failure.

3.Makecab.

Compressing a file is easy - makecab file.txt "file.cab" . Eventually MaxCabinetSize could be increased. Compressing a folder requires a usage DestinationDir directive (with relative paths) for every (sub)directory and the files within . Here's a script:

;@echo off

;;;;; rem start of the batch part  ;;;;;
; if "%~2" EQU "" (
;   echo invalid arguments.For help use:
;   echo %~nx0 /h
;)
;for %%a in (/h /help -h -help) do ( 
;   if "%~1" equ "%%~a" (
;       echo compressing directory to cab file  
;       echo %~nx0 directory cabfile
;       echo to uncompress use:
;       echo EXPAND cabfile -F:* .
;   )
; )
;
; set "dir_to_cab=%~f1"
;
; set "path_to_dir=%~pn1"
; set "dir_name=%~n1" 
; set "drive_of_dir=%~d1"
; set "cab_file=%~2"
;
; if not exist %dir_to_cab%\ (
;   echo no valid directory passed
;   exit /b 1
;)

;
;break>"%tmp%\makecab.dir.ddf"
;
;setlocal enableDelayedExpansion
;for /d /r "%dir_to_cab%" %%a in (*) do (
;   
;   set "_dir=%%~pna"
;   set "destdir=%dir_name%!_dir:%path_to_dir%=!"
;   (echo(.Set DestinationDir=!destdir!>>"%tmp%\makecab.dir.ddf")
;   for %%# in ("%%a\*") do (
;       (echo("%%~s#"  /inf=no>>"%tmp%\makecab.dir.ddf")
;   )
;)
;(echo(.Set DestinationDir=!dir_name!>>"%tmp%\makecab.dir.ddf")
;   for %%# in ("%~f1\*") do (
;       
;       (echo("%%~s#"  /inf=no>>"%tmp%\makecab.dir.ddf")
;   )

;makecab /F "%~f0" /f "%tmp%\makecab.dir.ddf" /d DiskDirectory1=%cd% /d CabinetNameTemplate=%cab_file%.cab
;del /q /f "%tmp%\makecab.dir.ddf"
;exit /b %errorlevel%

;;
;;;; rem end of the batch part ;;;;;

;;;; directives part ;;;;;
;;
.New Cabinet
.set GenerateInf=OFF
.Set Cabinet=ON
.Set Compress=ON
.Set UniqueFiles=ON
.Set MaxDiskSize=1215751680;

.set RptFileName=nul
.set InfFileName=nul

.set MaxErrors=1
;;
;;;; end of directives part ;;;;;

For decompression EXPAND cabfile -F:* . can be used.For extraction in Unix cabextract or 7zip can be used.

4. .NET and GZipStream

I preferred a Jscript.net as it allows a neat hybridization with .bat (no toxic output , and no temp files).Jscript does not allow passing a reference of object to a function so the only way I found to make it work is by reading/writing files byte by byte (so I suppose it's not the fastest way - how buffered reading/writing can be done?)Again can be used only with single files.

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

 %~n0.exe %*

endlocal & exit /b %errorlevel%


*/


import System;
import System.Collections.Generic;
import System.IO;
import System.IO.Compression;



    function CompressFile(source,destination){
        var sourceFile=File.OpenRead(source);
        var destinationFile=File.Create(destination);
        var output = new  GZipStream(destinationFile,CompressionMode.Compress);
        Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,destinationFile.Name, false);
        var byteR = sourceFile.ReadByte();
        while(byteR !=- 1){
            output.WriteByte(byteR);
            byteR = sourceFile.ReadByte();
        }
        sourceFile.Close();
        output.Flush();
        output.Close();
        destinationFile.Close();
    }

    function UncompressFile(source,destination){
        var sourceFile=File.OpenRead(source);
        var destinationFile=File.Create(destination);

        var input = new GZipStream(sourceFile,
            CompressionMode.Decompress, false);
        Console.WriteLine("Decompressing {0} to {1}.", sourceFile.Name,
                destinationFile.Name);

        var byteR=input.ReadByte();
        while(byteR !== -1){
            destinationFile.WriteByte(byteR);
            byteR=input.ReadByte();
        }
        destinationFile.Close();
        input.Close();


    }

var arguments:String[] = Environment.GetCommandLineArgs();

    function printHelp(){
        Console.WriteLine("Compress and uncompress gzip files:");
        Console.WriteLine("Compress:");
        Console.WriteLine(arguments[0]+" -c source destination");
        Console.WriteLine("Uncompress:");
        Console.WriteLine(arguments[0]+" -u source destination");


    }

if (arguments.length!=4){
    Console.WriteLine("Wrong arguments");
    printHelp();
    Environment.Exit(1);
}

switch (arguments[1]){
    case "-c":

        CompressFile(arguments[2],arguments[3]);
        break;
    case "-u":
        UncompressFile(arguments[2],arguments[3]);
        break;
    default:
        Console.WriteLine("Wrong arguments");
        printHelp();
        Environment.Exit(1);
}

这篇关于我COM preSS(/ ZIP)和uncom preSS(/解压缩)文件和批处理文件的文件夹,而无需使用任何外部工具如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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