anadem has asked for the wisdom of the Perl Monks concerning the following question:

I'm using Achive::Zip (with perl v5.14.4) to gather various log files on Windows. Unfortunately Windows Explorer cannot see any directories inside the zip file, though unzip, 7zip, winzip, etc can see them. I guess this can be waved aside as a Windows problem, not Perl, but any ideas will be helpful. Here's a minimal example:
# this is perlzip.pl use strict; use Archive::Zip; my @files_to_get = ( { files => "perlzip.pl" }, # in current directory { files => "\\alans\\dummy.txt" }, # in another dir ); my $zip = Archive::Zip->new(); # new zip object for packaging foreach my $href ( @files_to_get ) { my $file = $href->{"files"}; print( " adding $file\n" ); $zip->addFile( $file ); } $zip->writeToFileNamed( "MyZip.zip" ); exit;
To try that you need two files: ".\perlzip.pl" and "\alan\dummy.txt"
Using backslashes or forward-slashes as directory delimiters in the script makes no difference. In no case can Windows see paths in the zip file, and in all cases other zip tools can. Archive::Zip is probably using forward-slashes itself, which Windows is refusing to see.
If anyone can SUGGEST A SOLUTION it will be VERY much appreciated.

Replies are listed 'Best First'.
Re: Archive::Zip problem with Windows Explorer
by rjt (Curate) on Jul 20, 2013 at 02:56 UTC
        { files => "\\alans\\dummy.txt"  }, # in another dir

    Windows Explorer's zip browser does not handle absolute paths (or relative paths with .., or at least those outside the current directory IIRC). However, relative paths under the current directory are fine. So, you can, for example:

    use Cwd qw/getcwd abs_path/; my $orig_path = abs_path(getcwd); chdir '\\'; $zip->addFile('alans\dummy.txt'); $zip->addFile($orig_path . '\perlzip.pl'); $zip->writeToFileNamed($orig_path . '\MyZip.zip'); chdir $orig_dir;
Re: Archive::Zip problem with Windows Explorer
by pmqs (Friar) on Jul 20, 2013 at 16:02 UTC
    A Zip archive that contains files with absolute paths is strictly non-compliant with the zip specification. Below is taken from here
    4.4.17.1 The name of the file, with optional relative path. The path stored MUST not contain a drive or device letter, or a leading slash. All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' for compatibility with Amiga and UNIX file systems etc. If input came from standard input, there is no file name field.
    I assume that Windows Explorer is using the strict interpretation of the zip spec.

    The Archive::Zip docs do cover this in the addFile section

    NOTE that you should not (generally) use absolute path names in zip member names, as this will cause problems with some zip tools as well as introduce a security hole and make the zip harder to use.

    As mentioned already in Re: Archive::Zip problem with Windows Explorer Windows Explorer can display both the path & filename if it uses a relative path.

    Something like this (untested) should allow you to store your files using a relative path.

    foreach my $href ( @files_to_get ) { my $file = $href->{"files"}; print( " adding $file\n" ); my $name = $file; $name =~ s/^[A-Z]://; # remove drive $name =~ s#^[/\\]+##; # remove leading path delimiter $zip->addFile( $file, $name ); }