Converting ZIP files to 7Z archive file using VBScript and 7-Zip

Whilst storage is continuing to get cheaper all the time I occasionally find myself needing to save some space. Usually where some cloud storage and archiving of old material is involved. ZIP files are very convenient for compressing files, but sometimes I need to go a step further. In these cases I opt for the 7z archive file format used in the free and portable software 7-Zip as I’ve always ended up with a smaller archive file.

I finally got fed up of manually converting ZIP files to 7z and decided to write a little VBScript to do it for me (in Windows).

The script works by making use of the 7-Zip command line utility to carry out the decompression and compression work. The script expects to be passed one or more ZIP file paths; the idea being to add a shortcut to the script in your send to menu so you can pass it the ZIP files easily from within Windows explorer. Taking each file in turn the script copies it to a local directory (as file access for de-/compression tends to be quickest on local drives and often I’ll compress on a networked drive). Once there it decompresses the file and then re-compresses the extracted files into a 7z file. The resulting 7z file is then copied back to the original folder.

There are some things to be aware of when using this script:

  • The command line version of 7-Zip (included in the standard 7-Zip installation) must be installed to use this script.
  • The constant COMMAND_LINE_7ZIP_PATH should be set to the location of the z-Zip command line utility (7z.exe).
  • The constant WORKING_FOLDER should be set to be a local directory on your computer.
  • The constant WIN_MODE determines what state the DOS window that runs the commands is in when called. Setting the constant to 0 will hide the window entirely. Setting the constant to 7 will keep the window displayed but minimised. I’d recommend using this last one just in case there is an error with the archive processing and so you can check on the progress with larger archives.
  • The original ZIP file is not deleted by this script.
  • The working directory will be cleared down after use if the value of the constant CLEANUP is set to TRUE. If set to FALSE, the ZIP file, extracted files and 7z files will remain in the working directory.

The script below works for me and (as usual) is provided here with no guarantees, but in the hope that someone else finds it useful.

Option Explicit

'-----------------
' CONSTANTS START
'-----------------
'[These effectively are the settings for the application.]

'Full path to the 7Zip command line executable
Const COMMAND_LINE_7ZIP_PATH = "C:\Program Files\7-Zip\7z.exe"

'Temporary folder in which to carry out the intermediate work
Const WORKING_FOLDER = "C:\temp\zip-2-7zip_dir\"

'An extension added to the file name to produce an output folder
Const OUTPUT_FOLDER_EXTENSION = "-out"

'Name of the file used as the input in the working directory
Const INPUT_ZIP = "input.zip"

'Name of the file produced as the output in the working directory
Const OUTPUT_7Z = "output.7z"

'Run DOS commands as ...
'Const WIN_MODE =   'Console window hidden entirely
Const WIN_MODE =    'Console window minimised - so you can restore it and view progress when building larger archives

'Clear down the working directory when finished
Const CLEANUP = TRUE

'------------------
' CONSTANTS FINISH
'------------------


'-----------------------
' GLOBAL VARIABLE START
'-----------------------
Dim g_strFilename, g_strInputFile, g_strOutputFile
Dim g_intCounter, g_colArgs
Dim g_strMessage
'------------------------
' GLOBAL VARIABLE FINISH
'------------------------


'--------------------
' MAIN ROUTINE START
'--------------------
'Get the command line arguments for the script
Set g_colArgs = Wscript.Arguments
If g_colArgs.Count > 0 Then 'Each argument should be a ZIP file. '(Process each argument as though it is) For g_intCounter = 0 to g_colArgs.Count - 1 g_strFilename = Wscript.Arguments(g_intCounter) g_strMessage = g_strMessage & ProcessArgument(g_intCounter) Next 'Display an output message g_strMessage = "The following operations were undertaken:" & g_strMessage MsgBox g_strMessage, vbInformation, "Archive Conversion Complete"
Else 'If there's not even one argument/file to process then exit Msgbox "Please pass a file to this script", 48,"No File Provided" WScript.Quit
End If
'---------------------
' MAIN ROUTINE FINISH
'---------------------


'-----------------
' FUNCTIONS START
'-----------------
'Process an argument - i.e. a ZIP file
Function ProcessArgument(p_intParameter) 'If we have a ZIP file, process it If CheckFile(g_strFilename) then 'Clear the working directory ClearWorkingDirectory
 'Copy the zip file to the local working directory 'This way if we're reaching a limit on Dropbox or something we won't blow it g_strInputFile = CopyInputFile(g_strFilename)
 'Extract content of input file ExtractFromZIP(g_strInputFile)
 'Compress extracted files to new archive AddTo7Z GetExtractedOutputFolder(g_strInputFile), GetExtractedOutputArchivePath
 'Copy the zip file to the local working directory 'This way if we're reaching a limit on Dropbox or something we won't blow it g_strOutputFile = CopyOutputFile(GetExtractedOutputArchivePath, g_strFilename)
 'Clear the working directory If CLEANUP then ClearWorkingDirectory 'Add success details to output message queue ProcessArgument = ProcessArgument & vbCrLf & "Creation Complete on Archive (" & p_intParameter & ") = " & g_strOutputFile Else 'Add failure details to output message queue ProcessArgument = ProcessArgument & vbCrLf & "Failed to Process (" & p_intParameter & ") = " & g_strFilename End If
End Function


'Check an input file exsists and is a ZIP file
Function CheckFile(p_strFilePath) Dim objFSO 'Initialise Set objFSO = CreateObject("Scripting.FileSystemObject") CheckFile = FALSE 'Check the file exists and is a zip file If UCase(Right(p_strFilePath,4)) = ".ZIP" then If objFSO.FileExists(p_strFilePath) then CheckFile = TRUE End If End If
End Function


'Copy the ZIP file to the working directory
Function CopyInputFile(p_g_strFilename) Dim objFSO 'Initialise Set objFSO = CreateObject("Scripting.FileSystemObject") 'Copy ZIP file to working directory CopyInputFile = WORKING_FOLDER & INPUT_ZIP objFSO.CopyFile p_g_strFilename, CopyInputFile
End Function


'Copy the 7z file to the directory the input file came from
Function CopyOutputFile(p_str7ZFilePath, p_strOriginalFilePath) Dim objFSO, objFile 'Initialise Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile(p_strOriginalFilePath) 'Copy ZIP file to working directory CopyOutputFile = objFSO.GetParentFolderName(p_strOriginalFilePath) & "\" & objFSO.GetBaseName(p_strOriginalFilePath) & ".7z" objFSO.CopyFile p_str7ZFilePath, CopyOutputFile, True
End Function


'Extract the files and folders in the ZIP to the working directory output folder
Function ExtractFromZIP(p_g_strFilename) 'Extract files and folders from the ZIP file to the output directory in the working directory Execute7ZIPCommand "x """ & p_g_strFilename & """ -r -o""" & GetExtractedOutputFolder(p_g_strFilename) & """" ExtractFromZIP = TRUE
End Function


'Add the files from the output folder to a new 7z archive file in the working directory
Function AddTo7Z(p_strFolderPath, p_strOutputFilePath) 'Add files and folders to a new 7z archive file Dim strCommand 'Archive files to a 7z file format strCommand = "a -t7z" 'Archive to this file path strCommand = strCommand & " """ & p_strOutputFilePath & """" 'Archive the content of this folder and sub folders strCommand = strCommand & " -r """ & p_strFolderPath & "\*""" 'Use ultra compression strCommand = strCommand & " -mx9"
 'Remove any previous files Execute7ZIPCommand strCommand 'Return the path to the archive file AddTo7Z = p_strOutputFilePath
End Function


'Get the path to the output folder in the working directory
Function GetExtractedOutputFolder(p_g_strInputFile) 'Add the output folder extension test to the end of the input file path to give the output file path GetExtractedOutputFolder = p_g_strInputFile & OUTPUT_FOLDER_EXTENSION
End Function


'Get the path to the 7z archive file in the working directory
Function GetExtractedOutputArchivePath() 'Return the path of the output archive GetExtractedOutputArchivePath = WORKING_FOLDER & OUTPUT_7Z
End Function


'Get the name of the input file from its path
Function GetInputFileName(p_g_strFilename) 'Get the input file name from the input file path Dim objFSO, objFile Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile(p_g_strFilename) GetInputFileName = objFile.Name
End Function
'------------------
' FUNCTIONS FINISH
'------------------


'--------------------
' SUB-ROUTINES START
'--------------------
'Execute 7z from the command line
Sub Execute7ZIPCommand(p_strCommand) 'Execute a 7Zip command Dim objShell 'Initialise Set objShell = CreateObject("WScript.Shell") 'Execute command objShell.Run """" & COMMAND_LINE_7ZIP_PATH & """ " & p_strCommand, WIN_MODE, TRUE
End Sub


'Make the working directory (empty)
Sub ClearWorkingDirectory() 'Remove all files from the working folder Dim objShell Set objShell = CreateObject("WScript.Shell") 'Remove then create the working directory - to blitz any files in there and ensure our working directory exists objShell.Run "%comspec% /c rmdir /s /q """ & WORKING_FOLDER & """", WIN_MODE, TRUE objShell.Run "%comspec% /c mkdir """ & WORKING_FOLDER & """", WIN_MODE, TRUE
End Sub
'---------------------
' SUB-ROUTINES FINISH
'---------------------
Author: Stephen Millard
Tags: | scripting | vbs |

Buy me a coffeeBuy me a coffee



Related posts that you may also like to read