Zipfile.Save() method crashes when called from my script

Jul 12, 2013 at 6:39 PM
Edited Jul 12, 2013 at 10:22 PM
Hi Dino,

(Note: I’m addressing this post to Dino only because I’m suggesting there may be a bug in the library. However, all comments, especially those containing helpful suggestions, are welcome.) I apologize for the length of this post, but it takes quite a bit of space to communicate all the necessary information.

I’ve been struggling for several weeks to create a Powershell script that uses DotNetZip to archive (zip) a set of nested folders, and I think I’ve run into a bug in the library. I’ll lay it out for you, and maybe you can tell me what’s going on.

I'm running under Windows 7 SP1 Professional and PowerShell 3.0.

I’m using a slight modification of your ZipUp-Files script at the DotNetZip Home Page on MSDN. (http://archive.msdn.microsoft.com/DotNetZip/Wiki/View.aspx?title=PowerShell%20Example&referringTitle=Home) At least I was going to start there. Unfortunately, I didn’t get very far, because of this alleged bug.

Here is my script as it stands now. Most of the changes I’ve made deal with file and directory names to make the script compatible with my machine’s filesystem.
function ZipUp-Files ( $directory )
{
  $children = get-childitem -path $directory
  foreach ($o in $children) 
  {
    if (!$BaseDir -or ($BaseDir -eq "")) {
      $ix = $o.PSParentPath.IndexOf("::")
      $BaseDir = $o.PSParentPath.Substring($ix+2)
      $x = get-item $BaseDir
      $ix = $x.PSParentPath.IndexOf("::")
      $ParentOfBase = $x.PSParentPath.Substring($ix+2) + "\"
    }
 
    if ($o.Name -ne "TestResults" -and 
        $o.Name -ne "obj" -and 
        $o.Name -ne "bin" -and
       $o.Name -ne "NTUSER.DAT" -and
    $o.Name -ne "_tfs" -and 
    $o.Name -ne "notused" -and 
    $o.Name -ne "AppNote.txt" -and 
    $o.Name -ne "CodePlex-Readme.txt" -and 
    $o.Name -ne "ReadThis.txt" -and 
    $o.Name -ne "Ionic.snk" -and 
    $o.Name -ne "Ionic.pfx" -and 
    $o.Name -ne "Debug" -and 
    $o.Name -ne "Release" -and
    $o.Name -ne "Resources")
    {
      if ($o.PSIsContainer)
      {
        ZipUp-Files ( $o.FullName )
      }
      else 
      {
        #Write-output $o.FullName
        if ($o.Name  -and
          $o.Name -ne "" -and
          $o.Name -ne ".tfs-ignore" -and
          (!$o.Name.EndsWith("~")) -and
          (!$o.Name.EndsWith("#")) -and
          (!$o.Name.EndsWith(".cache")) -and
          (!$o.Name.EndsWith(".zip") )
        )
        {
          Write-output $o.FullName.Replace($ParentOfBase, "")
          $e= $zipfile.AddFile($o.FullName.Replace($ParentOfBase, ""))
        }
      }
    }
  }
}


$DotNetZip='C:\Windows\System32\WindowsPowerShell\v1.0\DotNetZip'
$DNZ = $DotNetZip
$PS = 'C:\PSScripts'       # Development area for my PowerShell scripts

Remove-Item 'c:\DotNetZip-src-v.zip' -Force -ea SilentlyContinue

[System.Reflection.Assembly]::LoadFrom($DNZ+'\Ionic.Zip.Dll') 
# [System.Reflection.Assembly]::LoadFrom("c:\\dinoch\\bin\\Ionic.Zip.dll");
$version = get-content -path $DNZ'\AssemblyInfo.cs' | select-string -pattern 'AssemblyFileVersion\("[0-9]+(\.([0-9]+|\*)){1,3}"\)'  |  %{$_ -replace "[^0-9.]",""}

$ZipFileName = 'c:\DotNetZip-src-v.zip'
$zipfile =  new-object Ionic.Zip.ZipFile($ZipFileName);
cd $DNZ; cd ..
ZipUp-Files "DotNetZip"
$zipfile.Save()
$zipfile.Dispose()

cd $PS
As suggested by $DotNetZip= immediately after the function portion of the script, on my machine, Powershell is installed at C:\Windows\System32\WindowsPowerShell\v1.0, and DotNetZip is stored in a directory therein. For the ISE host, that is sufficient. The variable $DotNetZip points to that directory, and Powershell_ISE is happy. I can run the script, which I have called ZipUp-Files-WFM.ps1 in that host all day long.

However, the Console-Host is an entirely story: when I attempt to run ZipUp-Files-WFM under simply Powershell, it results in an abnormal termination, with the following messages at the end.
. . . . . . . . . . . . . . . . . . . . . .

DotNetZip\License.zlib.txt
DotNetZip\License_1.txt
DotNetZip\PleaseDonate.txt
DotNetZip\PleaseDonate_1.txt
DotNetZip\Readme.txt
DotNetZip\Readme_1.txt
DotNetZip\Zipit.exe
Exception calling "Save" with "0" argument(s): "C:\Users\Walter\DotNetZip\Apps\ConvertFromCS-Zip.ps1"
At C:\PSScripts\ZipUp-Files-WFM.ps1:68 char:1
+ $zipfile.Save()
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FileNotFoundException
To me most of the error message is essentially nonsense. Maybe it means more to you.

The reason I suspect there is bug is that neither my $profile nor my script make any reference to the C:\Users\Walter directory, other than indirectly through $(PS)Home preference variables.

Furthermore, most of the method calls to Ionic.Zip.dll are content to use the $Home directory, and do so correctly. Only the Save() method call fails, and when it does, it yanks an (incorrect) pathname out of thin air. To me, that strongly suggests a bug somewhere in the method code.

Thanks in advance for your help,

Walter