zipped from files create compressed batch-file zip

batch-file - create - zip files from command line



secuencia de comandos por lotes para comprimir una carpeta sin usar software externo (2)

Con Shell.Application carpetas vacías de nivel de aplicación 1 siempre se omiten. Puede probarlas usted mismo seleccionando un grupo de archivos, incluidas las carpetas vacías, e intente pegarlas en un archivo comprimido a través de Windows Explorer (que en realidad es lo que usa la aplicación de shell). Como solución, puede copiar la carpeta que desee en otra carpeta vacía y comprimir la nueva carpeta. Luego, tendrá directorios vacíos de nivel 2 que deberían estar comprimidos.

Tengo una carpeta con la siguiente estructura

subcarpeta de la carpeta (vacía) subcarpeta file1.bat file2.bat file3.bat

¿Cómo hago para escribir un archivo por lotes para comprimir el contenido de la carpeta anterior sin usar softwares externos como winrar o 7zip?

Probé el siguiente código. Pero copiaría los contenidos en la carpeta temporal especificada sin la carpeta vacía y al intentar comprimir la carpeta solo se comprimiría el archivo1 y el archivo2 e ignoraría el resto de los contenidos.

Me gustaría poder comprimir la carpeta tal como está sin afectar la estructura.

No pude encontrar el motivo del problema. Cualquier ayuda es apreciada.

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


Como dijo npocmaka , Windows no puede agregar una sola carpeta vacía a un archivo zip, ya sea a través de scripts o arrastrando y soltando.

Pero me has inspirado. Decidí escribir una utilidad de compresión en JScript, solo para ver si podía. Para resolver su problema actual, agregué un cheque para las carpetas vacías. Si se encuentra una carpeta vacía, esta secuencia de comandos creará una nueva carpeta secundaria dentro llamada "(vacía)". Fue eso, agregar un archivo de 0 bytes, o lanzar un error y omitir la adición de la carpeta.

De todos modos, si desea probarlo, guarde este script con la extensión .bat y ejecútelo. Por supuesto, no es tan simple como su VBscript, pero tiene un mejor registro, manejo de errores y tiempos; y puede comprimir archivos individuales y carpetas.

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

La ventaja de usar JScript sobre VBScript aquí es que no hay necesidad de repetir el eco en _zipIt.vbs . JScript ofrece la posibilidad de ser evaluado en línea como un híbrido de un script por lotes. Su vbscript que saqueó tiene otro problema, ya que llama arbitrariamente a WScript.Sleep 2000 , independientemente de cuánto tiempo se necesita para completar la copia. Si está copiando archivos de gran tamaño, es posible que 2 segundos no sean suficientes. Y es un desperdicio si estás copiando algo pequeño.