Windows Vista Forums

Has anyone interfaced with the Vista/Xp zip dll's from vbs?
  1. #1


    Dick Guest

    Has anyone interfaced with the Vista/Xp zip dll's from vbs?

    I have a need to create several zip archives and then archive those into a
    single archive and copy that archive to external media (i.e. CDR, USB, etc).
    Currently, I'm using WinZip, but would like to not have to call a 3rd party
    program to accomplish my task. I use this utility on many machines. Using
    a 3rd party program has it's own set of problems: it can halt for a variety
    of reasons, etc.

    Has someone figured out how to interface with Windows built-in zip dll's? I
    figure it must require a Com object in order to call the zip dll's. Or has
    someone figured out another solution?



    Thanks in advance...

    Dick


      My System SpecsSystem Spec

  2. #2


    Paul Randall Guest

    Re: Has anyone interfaced with the Vista/Xp zip dll's from vbs?


    "Dick" <rsutton43@xxxxxx> wrote in message
    news:OjFrlgbpJHA.504@xxxxxx

    >I have a need to create several zip archives and then archive those into a
    >single archive and copy that archive to external media (i.e. CDR, USB,
    >etc). Currently, I'm using WinZip, but would like to not have to call a 3rd
    >party program to accomplish my task. I use this utility on many machines.
    >Using a 3rd party program has it's own set of problems: it can halt for a
    >variety of reasons, etc.
    >
    > Has someone figured out how to interface with Windows built-in zip dll's?
    > I figure it must require a Com object in order to call the zip dll's. Or
    > has someone figured out another solution?
    >
    > Thanks in advance...
    >
    > Dick
    My experience has shown that it can be done, but not in a graceful manner.
    It is easy to zip a folder and its contents. You just create an empty .zip
    file (a fixed byte pattern of less than 100 bytes, as I recall), then set up
    a shell folder object for that .zip file path (not a filesystem folder
    object) and execute this shell folder object's copyhere method to copy the
    collection of shell folder items of interest. Optionally you can have a
    progress bar, but the process becomes asynchronous to your script, so the
    script has no indication of when the zipping process is done. So your
    script might do an item count. But if any of the items are for hidden
    files, they are ignored, not coppied, so your counter won't work. To get
    around this, you could first copy everything you want zipped into a folder,
    and then zip that folder and its contents. This way you would only be
    zipping one thing - the folder - and hidden files within this folder would
    be zipped. But you may not want this additional container folder within
    your zip file. Messy. To get some sample code that includes building the
    empty zip file, try groups.google.com, searching for something like:
    empty zip group:*.scripting

    I think that adding files/folders one at a time to an existing .zip is
    resource intensive, possibly insignificant while the zip file is small, but
    probably significant when the zip file is large. So I generally tend to try
    to build the whole zip file at once.

    Note that using shell folder items, you can recurse through the zip
    file/folder structure, or .CAB file/folder structure, and can access the
    info for each item in all the columns that you see when you open the zip/cab
    as a file folder on your screen. Starting at the zip/cab file as the root
    folder, you can recurse through the normal file/nested folder structure
    within, but you are blocked from recursing into internal compressed
    file/folders. At least that is my experience. You might create a database
    of the CRC32 values listed in the zip folder windows, so you can find out
    fairly reliably which zip files contain the same or different versions of
    specific file names/paths.

    Here is my current zipper script.

    'Script to demo zipping all the files in a specified folder into a new
    ' .Zip file
    'Note: This demo does NOT have a direct method of monitoring progress.
    'The Shell Folder's CopyHere method starts an external process to
    ' do the actual copying; depending on options set, it may provide
    ' popup windows to show progress, ask what to do about
    ' collisions, etc. This external process does not show up in Task
    ' Manager.
    ' Note that any progress or other popup windows take focus away
    ' from whatever the user may be doing, or from other windows
    ' to which scripts may be sending keystrokes through the use
    ' of things like SendKeys or AutoIt.
    'This script overwrites the specified .Zip file, creating a new one,
    ' thus ensuring that completion can be assumed when the number of
    ' items in the .Zip file matches the number of items in the source
    ' folder.
    'Note that this code sets up a shell application folder object
    ' associated with the folder containing the stuff to be zipped.
    ' It zips the non-hidden items in that folder object. The
    ' Item and Items propertes do not include hidden items. It
    ' zips top level non-hidden items (files and folders), plus the
    ' contents (both hidden and non-hidden) of folders. The count of
    ' items is the number of top level items in the source folder.
    Option Explicit
    Dim iZippedItemCount
    Dim oFSO
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    MsgBox "Starting"

    Dim sCurrentFolder, sFolderPath, sFullZipPath
    sCurrentFolder = oFSO.GetParentFolderName(WScript.ScriptFullName)
    sFullZipPath = sCurrentFolder & "\dir.zip"
    sFolderPath = sCurrentFolder & "\CurntFlopy"

    iZippedItemCount = ZipAFolder(sFolderPath, sFullZipPath)
    MsgBox "Done: ZipFileCount = " & iZippedItemCount

    Function ZipAFolder(sFolderPath, sFullZipPath)
    'Note: any existing zip file at sFullZipPath is destroyed.
    'Creates a new zip file at sFullZipPath and
    ' copies all of the contents of sFolderPath into it.

    Dim oShellApp
    Set oShellApp = CreateObject("Shell.Application")
    Dim ZipInitialFileCount
    ZipInitialFileCount = oShellApp.NameSpace(sFolderPath).Items.Count

    ' Create an empty ZIP file
    CreateMTZip sFullZipPath

    ' Copy non-hidden files from sFolderPath into the ZIP file
    oShellApp.NameSpace(sFullZipPath).CopyHere _
    oShellApp.NameSpace(sFolderPath).Items
    ' Keep script waiting until compression is done
    'WScript.Sleep 1000
    On Error Resume Next
    Do Until oShellApp.NameSpace(sFullZipPath).Items.Count _
    = oShellApp.NameSpace(sFolderPath).Items.Count
    WScript.Sleep 200
    Loop
    On Error Goto 0

    ZipAFolder = oShellApp.NameSpace(sFolderPath).Items.Count
    End Function 'ZipAFolder(sFolderPath, sFullZipPath)

    Function CreateMTZip(sZipPath)
    'Creates OR overwrites the file sZipPath, with a binary string
    ' that represents the contents of an empty .Zip file/folder.
    'If the file name's extension is .zip, then WXPSP2 (and perhaps
    ' other Windows versions) will treat this file as an empty
    ' compressed folder.
    Dim sBinary 'String equivalent of empty .Zip file/folder.
    sBinary = "PK" & Chr(5) & Chr(6) & String(18, 0)
    With CreateObject("Scripting.FileSystemObject")
    .CreateTextFile(sZipPath, True, False).Write(sBinary)
    End With
    End Function 'CreateMTZip(sZipPath)

    ------------end of code------------

    -Paul Randall



      My System SpecsSystem Spec

  3. #3


    Dick Guest

    Re: Has anyone interfaced with the Vista/Xp zip dll's from vbs?


    <pryorm09@xxxxxx> wrote in message
    news:eedaf75b-32b1-4a53-9f49-b7324b235493@xxxxxx

    > On Mar 15, 2:51 pm, "Dick" <rsutto...@xxxxxx> wrote:

    >> I have a need to create several zip archives and then archive those into
    >> a
    >> single archive and copy that archive to external media (i.e. CDR, USB,
    >> etc).
    >> Currently, I'm using WinZip, but would like to not have to call a 3rd
    >> party
    >> program to accomplish my task. I use this utility on many machines.
    >> Using
    >> a 3rd party program has it's own set of problems: it can halt for a
    >> variety
    >> of reasons, etc.
    >>
    >> Has someone figured out how to interface with Windows built-in zip dll's?
    >> I
    >> figure it must require a Com object in order to call the zip dll's. Or
    >> has
    >> someone figured out another solution?
    >>
    >> Thanks in advance...
    >>
    >> Dick
    >
    > Sheesh, is there any fun in using windows except to try and figure out
    > stuff like this yourself?
    >
    > You are talking about
    > zipfldr.dll
    >
    > To see how it inserts itself into the shell and context menus, you
    > really should look at the
    > registry scripts that are wrapped into the DLL as a resource. You can
    > do that by opening the DLL as
    > a resource in Visual Studio resource editor, or though its awkward,
    > you can browse the DLL with
    > a Hex Editor like UltraEdit. Do an ASCII search for something like
    > "CompressedFolder" and you
    > will jump into the resource.
    >
    > What you will see is that the shell calls it using RunDLL entry
    > points, not via COM. I checked for
    > any COM functionality by searching with TLViewer (my App). I suspected
    > some COM abilities since it
    > gets registered with regsvr32, but that only seems to enter the
    > registry scripts already mentioned.
    >
    > You can get the exact RunDLL syntax by doing another hex read. I'm on
    > Centos right now so I can't
    > do that.
    >
    > --
    > Mark
    Mark,

    Thanks for the info. What I meant when I mentioned a COM object was
    something someone designed specifically to interface with the zip dll's. I
    was hoping that someone had already done that. I'm a little lazy to write
    the wrapper myself in C++ or whatever. It's usually not worth the work
    involved unless you do that kind of thing, everyday.

    You gave me some ideas, however, thanks for the info...

    Dick


      My System SpecsSystem Spec

  4. #4


    Dick Guest

    Re: Has anyone interfaced with the Vista/Xp zip dll's from vbs?


    "Paul Randall" <paulr90@xxxxxx> wrote in message
    news:e3ag6depJHA.504@xxxxxx

    >
    > "Dick" <rsutton43@xxxxxx> wrote in message
    > news:OjFrlgbpJHA.504@xxxxxx

    >>I have a need to create several zip archives and then archive those into a
    >>single archive and copy that archive to external media (i.e. CDR, USB,
    >>etc). Currently, I'm using WinZip, but would like to not have to call a
    >>3rd party program to accomplish my task. I use this utility on many
    >>machines. Using a 3rd party program has it's own set of problems: it can
    >>halt for a variety of reasons, etc.
    >>
    >> Has someone figured out how to interface with Windows built-in zip dll's?
    >> I figure it must require a Com object in order to call the zip dll's. Or
    >> has someone figured out another solution?
    >>
    >> Thanks in advance...
    >>
    >> Dick
    >
    > My experience has shown that it can be done, but not in a graceful manner.
    > It is easy to zip a folder and its contents. You just create an empty
    > .zip file (a fixed byte pattern of less than 100 bytes, as I recall), then
    > set up a shell folder object for that .zip file path (not a filesystem
    > folder object) and execute this shell folder object's copyhere method to
    > copy the collection of shell folder items of interest. Optionally you can
    > have a progress bar, but the process becomes asynchronous to your script,
    > so the script has no indication of when the zipping process is done. So
    > your script might do an item count. But if any of the items are for
    > hidden files, they are ignored, not coppied, so your counter won't work.
    > To get around this, you could first copy everything you want zipped into a
    > folder, and then zip that folder and its contents. This way you would
    > only be zipping one thing - the folder - and hidden files within this
    > folder would be zipped. But you may not want this additional container
    > folder within your zip file. Messy. To get some sample code that
    > includes building the empty zip file, try groups.google.com, searching for
    > something like:
    > empty zip group:*.scripting
    >
    > I think that adding files/folders one at a time to an existing .zip is
    > resource intensive, possibly insignificant while the zip file is small,
    > but probably significant when the zip file is large. So I generally tend
    > to try to build the whole zip file at once.
    >
    > Note that using shell folder items, you can recurse through the zip
    > file/folder structure, or .CAB file/folder structure, and can access the
    > info for each item in all the columns that you see when you open the
    > zip/cab as a file folder on your screen. Starting at the zip/cab file as
    > the root folder, you can recurse through the normal file/nested folder
    > structure within, but you are blocked from recursing into internal
    > compressed file/folders. At least that is my experience. You might
    > create a database of the CRC32 values listed in the zip folder windows, so
    > you can find out fairly reliably which zip files contain the same or
    > different versions of specific file names/paths.
    >
    > Here is my current zipper script.
    >
    > 'Script to demo zipping all the files in a specified folder into a new
    > ' .Zip file
    > 'Note: This demo does NOT have a direct method of monitoring progress.
    > 'The Shell Folder's CopyHere method starts an external process to
    > ' do the actual copying; depending on options set, it may provide
    > ' popup windows to show progress, ask what to do about
    > ' collisions, etc. This external process does not show up in Task
    > ' Manager.
    > ' Note that any progress or other popup windows take focus away
    > ' from whatever the user may be doing, or from other windows
    > ' to which scripts may be sending keystrokes through the use
    > ' of things like SendKeys or AutoIt.
    > 'This script overwrites the specified .Zip file, creating a new one,
    > ' thus ensuring that completion can be assumed when the number of
    > ' items in the .Zip file matches the number of items in the source
    > ' folder.
    > 'Note that this code sets up a shell application folder object
    > ' associated with the folder containing the stuff to be zipped.
    > ' It zips the non-hidden items in that folder object. The
    > ' Item and Items propertes do not include hidden items. It
    > ' zips top level non-hidden items (files and folders), plus the
    > ' contents (both hidden and non-hidden) of folders. The count of
    > ' items is the number of top level items in the source folder.
    > Option Explicit
    > Dim iZippedItemCount
    > Dim oFSO
    > Set oFSO = CreateObject("Scripting.FileSystemObject")
    > MsgBox "Starting"
    >
    > Dim sCurrentFolder, sFolderPath, sFullZipPath
    > sCurrentFolder = oFSO.GetParentFolderName(WScript.ScriptFullName)
    > sFullZipPath = sCurrentFolder & "\dir.zip"
    > sFolderPath = sCurrentFolder & "\CurntFlopy"
    >
    > iZippedItemCount = ZipAFolder(sFolderPath, sFullZipPath)
    > MsgBox "Done: ZipFileCount = " & iZippedItemCount
    >
    > Function ZipAFolder(sFolderPath, sFullZipPath)
    > 'Note: any existing zip file at sFullZipPath is destroyed.
    > 'Creates a new zip file at sFullZipPath and
    > ' copies all of the contents of sFolderPath into it.
    >
    > Dim oShellApp
    > Set oShellApp = CreateObject("Shell.Application")
    > Dim ZipInitialFileCount
    > ZipInitialFileCount = oShellApp.NameSpace(sFolderPath).Items.Count
    >
    > ' Create an empty ZIP file
    > CreateMTZip sFullZipPath
    >
    > ' Copy non-hidden files from sFolderPath into the ZIP file
    > oShellApp.NameSpace(sFullZipPath).CopyHere _
    > oShellApp.NameSpace(sFolderPath).Items
    > ' Keep script waiting until compression is done
    > 'WScript.Sleep 1000
    > On Error Resume Next
    > Do Until oShellApp.NameSpace(sFullZipPath).Items.Count _
    > = oShellApp.NameSpace(sFolderPath).Items.Count
    > WScript.Sleep 200
    > Loop
    > On Error Goto 0
    >
    > ZipAFolder = oShellApp.NameSpace(sFolderPath).Items.Count
    > End Function 'ZipAFolder(sFolderPath, sFullZipPath)
    >
    > Function CreateMTZip(sZipPath)
    > 'Creates OR overwrites the file sZipPath, with a binary string
    > ' that represents the contents of an empty .Zip file/folder.
    > 'If the file name's extension is .zip, then WXPSP2 (and perhaps
    > ' other Windows versions) will treat this file as an empty
    > ' compressed folder.
    > Dim sBinary 'String equivalent of empty .Zip file/folder.
    > sBinary = "PK" & Chr(5) & Chr(6) & String(18, 0)
    > With CreateObject("Scripting.FileSystemObject")
    > .CreateTextFile(sZipPath, True, False).Write(sBinary)
    > End With
    > End Function 'CreateMTZip(sZipPath)
    >
    > ------------end of code------------
    >
    > -Paul Randall
    >
    Thanks, Paul.

    I'll take a look at your code and I'll google the groups as you suggested.
    My current solution uses WinZip but as I said in the original message that
    using WinZip is easy & clean but has it's own set of problems (like if a
    file is in use).

    Thanks again...

    Dick



      My System SpecsSystem Spec

Has anyone interfaced with the Vista/Xp zip dll's from vbs? problems?