0

I made this script based on past answers from superuser, but now need to only archive specific file types. I messed around trying to use wildcards but nothing I tried seemed to stick.

If I wanted to change this script to filter by specific file-types instead of all file system objects, what needs to be changed and how? For example, if I wanted to only archive DLL files, or DLL & EXE files, how would it be changed?

'To use this at command-line, call `CScript.exe zip_it.vbs SourceDirectory PathToOutputZipFileIncludingDotZipExt`
Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set shell = CreateObject("Shell.Application")
Set source_objects = shell.NameSpace(SourceDir).Items
shell.NameSpace(ZipFile).CopyHere(source_objects)
wScript.Sleep 400
1

You can use a filter. The magic is here:

SHCONTF_NONFOLDERS = 64
colFolderItems.Filter SHCONTF_NONFOLDERS, "*.ext"

Here it is in context with your code:

'To use this at command-line, call `CScript.exe zip_it.vbs SourceDirectory PathToOutputZipFileIncludingDotZipExt "file.pattern"`
Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
FileFilter = parameters(2)
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set shell = CreateObject("Shell.Application")
Set source_objects = shell.NameSpace(SourceDir).Items
SHCONTF_NONFOLDERS = 64
source_objects.Filter SHCONTF_NONFOLDERS, FileFilter
shell.NameSpace(ZipFile).CopyHere(source_objects)
wScript.Sleep 400

This can be called with "*.txt" to select only text files, or "*.exe" to collect only exe files. Also note that it doesn't play well if there is no file filter included.

However, your code is designed to recreate the ZIP each time, so you'd need to test for the existence of the file first if you want to call repeatedly for additional file types. This change does that:

If Not FS.FileExists (ZipFile) Then
    CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
End If

This does have a side-effect of popping (and almost immediately hiding) an overwrite prompt if the files already exist in the zip file. With that change you could do this:

cscript //nologo zip_it.vbs thefolder thefile.zip "*.txt"
cscript //nologo zip_it.vbs thefolder thefile.zip "*.doc"

It could be changed to iterate file types or extensions and collect all files if there is no filter, as so:

'To use this at command-line, call `CScript.exe zip_it.vbs SourceDirectory PathToOutputZipFileIncludingDotZipExt "file.pattern" "file2.pattern"`
Set parameters = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
SourceDir = FS.GetAbsolutePathName(parameters(0))
ZipFile = FS.GetAbsolutePathName(parameters(1))
SHCONTF_NONFOLDERS = 64

If Not FS.FileExists (ZipFile) Then
    CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
End If

Set shell = CreateObject("Shell.Application")

If parameters.Count > 2 Then
    For lParams = 2 to (parameters.Count-1)
        FileFilter = parameters(lParams)
        Set source_objects = shell.NameSpace(SourceDir).Items
        source_objects.Filter SHCONTF_NONFOLDERS, FileFilter
        shell.NameSpace(ZipFile).CopyHere(source_objects)
        wScript.Sleep 400
    Next
Else
    Set source_objects = shell.NameSpace(SourceDir).Items
    shell.NameSpace(ZipFile).CopyHere(source_objects)
    wScript.Sleep 400
End If

This could be called like:

cscript //nologo zip_it.vbs thefolder thefile.zip "*.doc" "*.txt"
10
  • I like your changes, but unfortunately as-written it's falling a little short. For one, it can only handle file-filters if that specific file-type exists directly in the source directory sent as the parameter. For another, even if it does, it won't find any in sub-directories. Interestingly enough, neither of our scripts seem to handle huge directories recursively; only small ones which is distressing! I didn't realize mine was so weak :( – kayleeFrye_onDeck Nov 22 '18 at 4:37
  • 1
    There are other items in the enumeration that might allow you to filter using parameters that more accurately represent your needs. The _SHCONTF enum supports 13 different values, and SHCONTF_FLATLIST or SHCONTF_CHECKING_FOR_CHILDREN might do what you're after. – shawn Dec 5 '18 at 18:55
  • I tried a lot of combinations, but could never get sub-directories zipping too. All I did was make a directory with a text file, then made another directory and put a text file in that. Both were populated with some data. If the combo even included an item, it would only be one of the two items. If you're able to get that use-case working, I will accept this answer so long as it isn't a cheesy hack (eg, sub-sub directories not working xD) – kayleeFrye_onDeck Dec 7 '18 at 2:40
  • My answer above does answer the question you asked. You didn't mention subdirectories, you specifically asked for file types. The Folder object (created by the shell.Namespace() lines) represents a specific folder. It does not represent each child folder or the child items within those child folders, which is why the filter method only checks the current Items collection for matches. – shawn Dec 8 '18 at 7:50
  • To filter items within the subdirectories you'll need to alter the code to recurse into child folders using IsFolder/GetFolder and check each child item with another Filter. Be aware that doing it this way will require you to manually recreate the directory structure within the zip (which works fine with NewFolder, btw) though, since CopyHere doesn't preserve Parent objects. – shawn Dec 8 '18 at 7:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.