Zipping in asp classic

Aug 13, 2009 at 1:45 PM

I have managed to work out how to read a zip file in asp (VBScript) but cannot extract because (I think) the Extract method will not accept an argument for the baseDirectory (or anything else).

If I could find a way to set the current directory in ASP that would be cool too but doesn't seem to be a way.

When I try to extract using entry.Extract() I get the message Ionic.Zip (0x80131500)
Cannot extract

Any ideas greatly appreciated


Coordinator
Aug 13, 2009 at 3:31 PM

To set the current directory, you can use WScript.Shell object and set the CurrentDirectory property. Not sure if this works in ASP. (I'm not an ASP expert).

Why still writing in ASP?    Why not write the page in ASP.NET?  It would be simpler.  anyway here's the VBSCript code.

Sub listAndMaybeExtractZip()

    WScript.echo("")
    Dim zip
    WScript.echo("Instantiating another ZipFile object...")
    Set zip = CreateObject("Ionic.Zip.ZipFile")
    
    WScript.echo("Initialize (Read)...")
    zip.Initialize(filename)

    If Not (extractLocation = "") Then
        CreateExtractDirectory(extractLocation)

        Set objShell = CreateObject("Wscript.Shell")
        objShell.CurrentDirectory = extractLocation
        WScript.echo("listing and extracting entries...")
    else
        WScript.echo("listing entries...")
    End If

    For Each entry in zip
        WScript.echo("  " & entry.FileName)

        If Not (extractLocation = "") Then
            ext = Right(entry.FileName,4)
            If (ext = ".vbs") Then
                If Not (password = "") Then
                    entry.Password = password
                End If
                ' extract into current directory
                entry.Extract()
            End If
        End If
    Next

    WScript.echo("Disposing...")
    zip.Dispose()

    WScript.echo("Done.")
End Sub

Aug 13, 2009 at 11:42 PM

Yeah there are probably good reasons to go to ASP.NET but to be honest I don't even know where to start and it is not my core business, so was hoping for a quick solution.

I have used the sample code you supply as the base but as I mentioned the entry.Extract method wants to put the file in the current directory and there is no way that I know of in ASP to set the default directory. I have tried using entry.Extract(baseDirectory) but I'm guessing that is not available in the COM implementation because I get invalid argument errors.

I can't find a reference for the error number so I am only making these assumptions based on other tests.

Thanks

 

 

Coordinator
Aug 14, 2009 at 2:20 AM

error 0x80131500  translates to "unknown error".  It really isn't unknown, though. The problem with caling Extract() from COM is that there are multiple overloads of the Extract() method, and there is no way to determine which overload you are asking for, by parameter type alone.

If you don't mind extracting all the files, you can call ZipFile.ExtractAll().  There's also an overload that lets you specify the path to extract to.

 

 

Aug 14, 2009 at 3:30 AM

Thanks Cheeso. That works.

ZipFile.ExtractAll(targetDirectory)

It seems that the methods require 1 and only 1 parameter. If I try to use the extractExistingFile parameter it fails. Which means clearing the target Directory before each run. Not a problem really.

I would love to be able to use the ExtractSelectedEntries method as I only need to extract one file from each archive but that would require using at least 3 parameters (to set the targetDirectory) and it fails. Is it possible to pass more than one parameter some how, or some other workaround.

But in the meantime I am up and going. Thanks again.

 

 

Coordinator
Aug 14, 2009 at 6:39 AM
Edited Aug 14, 2009 at 2:38 PM

Calling the Extractall() method with the extractExistingFile param, runs into the same problem.  There's an overload with the same number of parameters.  That happened for lots of members, when I modified the design.  See, originally there was a boolean true/false value for the overwrite parameter.  If you passed false, it would throw an exception if there was an existing file.  If you passed true, it would overwrite an existing file.  There was no way to tell the library to NOT overwrite an existing file and also not throw an exception.  So I created new methods, that accepted an enum parameter instead of a boolean.  The enum allows more control over what to do with existing files.

But, I couldn't remove the old members because that would cause older apps to fail to compile. So all the new methods (with the enum) have the same number of parameters as the older methods (with the boolean), and because of that, COM cannot call those methods.  Well, not by their regular name anyway.

But this is worth trying::  when .NET dynamically builds type libraries COM-callable wrappers, it appends  _2, _3, and so on, to overloaded methods. 

So, can you try:

  Dim OverwriteSilently
  OverwriteSilently = 1
  zip.ExtractSelectedEntries_5  "name = TheFileYouWant.txt", Null, extractLocation, OverwriteSilently

 

Aug 14, 2009 at 11:38 AM

That's awesome. A little bit of testing and it's up and going.

Now that I know that trick I should be able to work around most issues (after guessing what the serial no for the overload method is)

I notice that ExtractAll creates the extractLocation folder if it doesn't exist where ExtractSelectedEntries doesn't. Not a problem just an observation.

And it is really quick I need to extract 1 file from many archives. I just ran a test through that took about a minute to extract files from 2350 archives and involved copying them and renaming, Brilliant!

The last thing I noticed and this may be normal, but I had to destroy the object (Set objZip = Nothing) and recreate it each time before using a new archive or I got errors (not a valid zip file) after 2 iterations. I am using objZip.Dispose() but that just gets me one more iteration before it errors.

I'm thinking there maybe a lot of happy Classic ASP'ers out there when they find this can work for them.

Coordinator
Aug 14, 2009 at 12:25 PM

Sounds like some good tips there.  I'll modify the documentation for COM users on those things...

Glad its working for you.

 

Aug 15, 2009 at 8:12 PM

Hey, Cheeso - firstly thanks for a great library, i love it. And your support (i've been reading the discussions) is nothing short of outstanding.

As this thread was chatting about COM Interop i was thinking how i can use the information in this thread.  I use Vba quite a bit and still use VbScript\asp - It would be great if you could make the the type libraries generated from TLBEXP.EXE show the mehods . So we could use this library in VBA projects, I'm thinking Access and Excel with itellisense.  You can't add the dll currently as a reference, you can add the typelibrary (haven't tried using it as the public methods aren't shown on the classes. The intelisence may help with your overloaded method suggestion above.

I'm no expert or have no idea about the implications of doing this but it looks like every public methods need to implement an Interface and each public class implements the attribute ClassInterface(ClassInterfaceType.None)] - well thats what i was reading here http://www.15seconds.com/issue/040722.htm

Perhaps a future/dedicated version - a lot of apps get written in Access and Excel especially Excel as departmental automation tools, that go way beyond the applications purpose. They provide such a convienient well known interface, and everyones got them installed. 

Anyway as i say i'm no expert, the idea may have implications on your design that you do not want to go down

Matt

 

 

Coordinator
Aug 15, 2009 at 10:32 PM

Hey Matt,

It's a good idea.  The right thing to do.  There are a couple of reasons why I haven't done that. 

First, I'm lazy.  Second, no one has really asked for the typelib, until you.   Third, I don't really want to test it (which is really just another way of saying, "I'm lazy.")

But I will make it an official workitem.  And we'll see how much interest we get!

 

Coordinator
Aug 15, 2009 at 10:32 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.