Índice de la sección dedicada a .NET (en el Guille) Cómo... en .NET

Comprimir/descomprimir en .NET
(usando SharpZipLib.dll)

Código para Visual Basic.NET (VB.NET)

Código para C Sharp (C#)


Publicado el 17/Dic/2002
Actualizado el 20/Dic/2002

 

El código que te muestro en este artículo es una pequeña utilidad (de demostración) que sirve para comprimir/descomprimir ficheros en formato ZIP usando para ello una librería "gratuita" proporcionada por Mike Krueger, el creador de SharpDevelop, (un entorno de desarrollo gratuito para .NET); en el siguiente link puedes bajarte tanto el código fuente de la librería, la propia librería ya compilada así como también algunos ejemplos para usar: http://www.icsharpcode.net/OpenSource/SharpZipLib/.

Para este ejemplo que te muestro, he creado una clase con algunos métodos para comprimir y descomprimir ficheros con formato ZIP, (la librería también maneja otros formatos).

Además de la utilidad de comprimir, también incluyo una clase para simular las líneas 3D (usando dos etiquetas).
Y si tienes la beta del Visual Studio .NET 2003 (o a lo mejor lees esto cuando existan nuevas versiones de Visual Basic .NET), en el código de VB tienes (en bloques #IF) cómo se podrán usar las variables declaradas junto al For o For Each; y tanto para VB como para C#, tienes el código que habría que usar para seleccionar un directorio mediante la clase FolderBrowserDialog.

Este es el link para los listados de ejemplo, tanto para VB como para C#: tZipNET.zip (463 KB)
 

Nota del 20/Dic/02:

He modificado el código publicado originalmente con estas cosillas:
-en los proyectos había paths que no existían,
-al comprimir se guarda la fecha de la última modificación, (antes se guardaba la fecha actual),
-cuando se comprime se guarda el path completo, pero, aunque está comentado, he añadido código para que se pueda guardar sólo el nombre o el path sin el primer nivel,
-al descomprimir si el path de destino no existe, se crea,
-y algunas "pequeñeces" más.
 

En el zip también se incluye 031SharpZipLib.zip que es la versión que había cuando publiqué este artículo, en ese zip está la dll así como la documentación y el copyright de la librería.
Te recomiendo que de vez en cuando te des una vuelta por el sitio de SharpZipLib para ver si hay actualizaciones.

¡Que lo disfrutes!

Nos vemos.
Guillermo



El formulario en tiempo de ejecución


Código para Visual Basic.NET (VB.NET)

Aquí tienes los links para las diferentes clases (para VB .NET):

La clase ZipUtil

'------------------------------------------------------------------------------
' ZipUtil                                                           (16/Dic/02)
' utilidad para comprimir/descomprimir ficheros zips
' usando SharpZipLib.dll
'
' ©Guillermo 'guille' Som, 2002
'------------------------------------------------------------------------------
Imports ICSharpCode.SharpZipLib.Zip
Imports ICSharpCode.SharpZipLib.Checksums
Imports System.IO

Public Class ZipUtil
    Public Sub Comprimir(ByVal directorio As String, _
                         ByVal filtro As String, _
                         ByVal zipFic As String, _
                         Optional ByVal crearAuto As Boolean = True)
        ' comprimir los ficheros del directorio indicado
        ' y guardarlo en el zip
        ' en filtro se indicará el filtro a usar para seleccionar los ficheros del directorio
        ' si directorio es una cadena vacía, filtro será el fichero a comprimir (sólo ese)
        ' si crearAuto = True, zipfile será el directorio en el que se guardará
        ' y se generará automáticamente el nombre con la fecha y hora actual
        '
        Dim fileNames(0) As String
        If directorio = "" Then
            fileNames(0) = filtro
        Else
            fileNames = Directory.GetFiles(directorio, filtro)
        End If
        '
        ' llamar a la versión sobrecargada que recibe un array
        Comprimir(fileNames, zipFic, crearAuto)
    End Sub
    '
    Public Sub Comprimir(ByVal fileNames() As String, _
                         ByVal zipFic As String, _
                         Optional ByVal crearAuto As Boolean = False)
        ' comprimir los ficheros del array en el zip indicado
        ' si crearAuto = True, zipfile será el directorio en el que se guardará
        ' y se generará automáticamente el nombre con la fecha y hora actual
        Dim objCrc32 As New Crc32()
        Dim strmZipOutputStream As ZipOutputStream
        '
        If zipFic = "" Then
            zipFic = "."
            crearAuto = True
        End If
        If crearAuto Then
            ' si hay que crear el nombre del fichero
            ' éste será el path indicado y la fecha actual
            zipFic &= "\ZIP" & DateTime.Now.ToString("yyMMddHHmmss") & ".zip"
        End If
        strmZipOutputStream = New ZipOutputStream(File.Create(zipFic))
        ' Compression Level: 0-9
        ' 0: no(Compression)
        ' 9: maximum compression
        strmZipOutputStream.SetLevel(6)
        '
        Dim strFile As String
        For Each strFile In fileNames
            Dim strmFile As FileStream = File.OpenRead(strFile)
            Dim abyBuffer(Convert.ToInt32(strmFile.Length - 1)) As Byte
            '
            strmFile.Read(abyBuffer, 0, abyBuffer.Length)
            '
            '------------------------------------------------------------------
            ' para guardar sin el primer path
            'Dim sFile As String = strFile
            'Dim i As Integer = sFile.IndexOf("\")
            'If i > -1 Then
            '    sFile = sFile.Substring(i + 1).TrimStart
            'End If
            '------------------------------------------------------------------
            '
            '------------------------------------------------------------------
            ' para guardar sólo el nombre del fichero
            ' esto sólo se debe hacer si no se procesan directorios
            ' que puedan contener nombres repetidos
            'Dim sFile As String = Path.GetFileName(strFile)
            'Dim theEntry As ZipEntry = New ZipEntry(sFile)
            '------------------------------------------------------------------
            '
            ' se guarda con el path completo
            Dim theEntry As ZipEntry = New ZipEntry(strFile)
            '
            ' guardar la fecha y hora de la última modificación
            Dim fi As New FileInfo(strFile)
            theEntry.DateTime = fi.LastWriteTime
            'theEntry.DateTime = DateTime.Now
            '
            theEntry.Size = strmFile.Length
            strmFile.Close()
            objCrc32.Reset()
            objCrc32.Update(abyBuffer)
            theEntry.Crc = objCrc32.Value
            strmZipOutputStream.PutNextEntry(theEntry)
            strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)
        Next
        strmZipOutputStream.Finish()
        strmZipOutputStream.Close()
    End Sub
    '
    Public Sub Descomprimir(ByVal directorio As String, _
                            Optional ByVal zipFic As String = "", _
                            Optional ByVal eliminar As Boolean = False, _
                            Optional ByVal renombrar As Boolean = False)
        ' descomprimir el contenido de zipFic en el directorio indicado.
        ' si zipFic no tiene la extensión .zip, se entenderá que es un directorio y
        ' se procesará el primer fichero .zip de ese directorio.
        ' si eliminar es True se eliminará ese fichero zip después de descomprimirlo.
        ' si renombrar es True se añadirá al final .descomprimido
        If Not zipFic.ToLower.EndsWith(".zip") Then
            zipFic = Directory.GetFiles(zipFic, "*.zip")(0)
        End If
        ' si no se ha indicado el directorio, usar el actual
        If directorio = "" Then directorio = "."
        '
        Dim z As New ZipInputStream(File.OpenRead(zipFic))
        Dim theEntry As ZipEntry
        '
        Do
            theEntry = z.GetNextEntry()
            If Not theEntry Is Nothing Then
                Dim fileName As String = directorio & "\" & Path.GetFileName(theEntry.Name)
                '
                ' dará error si no existe el path
                Dim streamWriter As FileStream
                Try
                    streamWriter = File.Create(fileName)
                Catch ex As DirectoryNotFoundException
                    Directory.CreateDirectory(Path.GetDirectoryName(fileName))
                    streamWriter = File.Create(fileName)
                End Try
                '
                Dim size As Integer
                Dim data(2048) As Byte
                Do
                    size = z.Read(data, 0, data.Length)
                    If (size > 0) Then
                        streamWriter.Write(data, 0, size)
                    Else
                        Exit Do
                    End If
                Loop
                streamWriter.Close()
            Else
                Exit Do
            End If
        Loop
        z.Close()
        '
        ' cuando se hayan extraído los ficheros, renombrarlo
        If renombrar Then
            File.Copy(zipFic, zipFic & ".descomprimido")
        End If
        If eliminar Then
            File.Delete(zipFic)
        End If
    End Sub
    '
    Public Function Contenido(ByVal zipFic As String) As ZipEntry()
        ' devuelve el contenido del zip indicado
        Dim strmZipInputStream As ZipInputStream = New ZipInputStream(File.OpenRead(zipFic))
        Dim objEntry As ZipEntry
        'Dim strOutput As String
        Dim files() As ZipEntry
        Dim n As Integer = -1
        'Dim strBuilder As System.Text.StringBuilder = New System.Text.StringBuilder(strOutput)
        '
        objEntry = strmZipInputStream.GetNextEntry()
        While IsNothing(objEntry) = False
            n = n + 1
            ReDim Preserve files(n)
            files(n) = objEntry
            objEntry = strmZipInputStream.GetNextEntry()
        End While
        strmZipInputStream.Close()
        '
        Return files
    End Function
End Class

La clase cLine3DEx

'------------------------------------------------------------------------------
' cLine3DEx para vb.NET                                             (19/Nov/01)
'
' xShadowLine                                                       (29/Ago/98)
' Line3DEx Nuevo nombre y nuevas propiedades                        (16/Ene/99)
'
' Un control MUY simple para simular líneas sombreadas (3D)
'
'
' ©Guillermo 'guille' Som, 1998-2002
'------------------------------------------------------------------------------

Public Class cLine3DEx
    Private m_Inset As Boolean = True
    '
    Private ColorOscuro As System.Drawing.Color = Color.FromKnownColor(KnownColor.ControlDark)
    Private ColorClaro As System.Drawing.Color = Color.FromKnownColor(KnownColor.ControlLightLight)
    '
    ' Si se ajusta automáticamente al ancho del contenedor
    Private m_AdjustWidth As Boolean
    ' Separación desde la izquierda del borde del contenedor        (18/Ene/99)
    ' (este mismo valor se aplica a la derecha)
    Private m_IndentValue As Integer
    ' Variables para las dos etiquetas que se usarán
    Private mLine1(1) As Label
    ' Contenedor de las etiquetas
    Private mContenedor As ContainerControl
    ' Posición de la línea
    Private mLeft As Integer
    Private mWidth As Integer
    '
    Public Sub New(ByVal Label1 As Label, ByVal Label2 As Label, ByVal Contenedor As ContainerControl)
        MyBase.New()
        m_Inset = True
        m_AdjustWidth = False
        m_IndentValue = 4
        mContenedor = Contenedor
        mLine1(0) = Label1
        mLine1(1) = Label2
        mLine1(1).SendToBack()
        With mLine1(0)
            .BackColor = ColorOscuro
            .Height = 1
            .Left = m_IndentValue
        End With
        With mLine1(1)
            .BackColor = ColorClaro
            .Height = 1
            .Top = mLine1(0).Top + 1
            .Left = m_IndentValue
        End With
    End Sub
    '
    Public Property AdjustWidth() As Boolean
        Get
            Return m_AdjustWidth
        End Get
        Set(ByVal Value As Boolean)
            ' Si se ajusta automáticamente al ancho del contenedor
            m_AdjustWidth = Value
            UserControl_Resize()
        End Set
    End Property
    '
    Public Property IndentValue() As Integer
        Get
            Return m_IndentValue
        End Get
        Set(ByVal Value As Integer)
            m_IndentValue = Value
            ' Reajustar el tamaño de las líneas
            UserControl_Resize()
        End Set
    End Property
    '
    Public Property Inset() As Boolean
        Get
            Return m_Inset
        End Get
        Set(ByVal Value As Boolean)
            m_Inset = Value
            UserControl_Resize()
        End Set
    End Property
    '
    Public Property Raised() As Boolean
        Get
            Return m_Inset
        End Get
        Set(ByVal Value As Boolean)
            m_Inset = Not Value
            UserControl_Resize()
        End Set
    End Property
    '
    Public Sub Resize()
        ' Método para ajustar el tamaño de las líneas
        ' normalmente se usará en el evento Resize del contenedor
        UserControl_Resize()
    End Sub

    Private Sub UserControl_Resize()
        '
        ' Si se debe ajustar automáticamente al ancho del contenedor
        If m_AdjustWidth Then
            If TypeOf mContenedor Is Panel Then
                mLeft = 1
            Else
                mLeft = 0
            End If
            ' Si se especifica el valor de indentación
            mLeft = mLeft + m_IndentValue
            mWidth = mContenedor.DisplayRectangle.Width - (mLeft * 2)
        End If
        '
        With mLine1(0)
            If m_Inset Then
                .BackColor = ColorOscuro
            Else
                .BackColor = ColorClaro
            End If
            .Width = mWidth
            .Left = mLeft
        End With
        With mLine1(1)
            If m_Inset Then
                .BackColor = ColorClaro
                .BringToFront()
            Else
                .BackColor = ColorOscuro
                .SendToBack()
            End If
            .Width = mWidth
            .Left = mLeft
        End With
        '
    End Sub
End Class

El formulario de ejemplo

'------------------------------------------------------------------------------
' Utilidad para comprimir/descomprimir ficheros                     (16/Dic/02)
' usando SharpZipLib.dll
'
' ©Guillermo 'guille' Som, 2002
'------------------------------------------------------------------------------
' En este ejemplo utilizo esta constante para indicar si el código
' es compatible con el VS 2002 o para versiones posteriores
' En el caso de las versiones posteriores, se usan los bucles
' con la variable declarada junto al For o ForEach y
' para seleccionar directorios se usa la nueva clase FolderBrowserDialog
#Const VS2002 = True

Imports ICSharpCode.SharpZipLib.Zip

Public Class fZipTest
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
'...
#End Region
    '
    Private iniciando As Boolean = True
    Private linea3D As cLine3DEx
    Private openFD As New OpenFileDialog
    Private zUtil As New ZipUtil
    '
    Private Sub fZipTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        linea3D = New cLine3DEx(linea1, linea2, Me)
        linea3D.AdjustWidth = True
        '
        zipFicTextBox.Text = ""
        unZipDirTextBox.Text = ""
        zipButton.Enabled = False
        '
        iniciando = False
    End Sub

    Private Sub fZipTest_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
        If iniciando Then Exit Sub
        If WindowState <> FormWindowState.Minimized Then
            linea3D.Resize()
        End If
    End Sub

    Private Sub cerrarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cerrarButton.Click
        Me.Close()
    End Sub

    Private Sub examinarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles examinarButton.Click
        ' seleccionar el fichero ZIP con el que se va a trabajar
        With openFD
            .Title = "Selecciona el fichero ZIP"
            .Filter = "Ficheros ZIPs (*.zip)|*.zip|Todos los ficheros (*.*)|*.*"
            .FileName = Me.zipFicTextBox.Text
            .Multiselect = False
            ' para que se puede indicar un fichero que no existe
            .CheckFileExists = False
            If .ShowDialog = DialogResult.OK Then
                zipFicTextBox.Text = .FileName
            End If
        End With
    End Sub

    Private Sub addButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addButton.Click
        ' añadir ficheros a la lista
        With openFD
            .Title = "Selecciona los ficheros a comprimir"
            .Filter = "Código|*.vb*;*.c*;*.pas;*.h*;*.bas;*.pr*;|Todos los ficheros (*.*)|*.*"
            .Multiselect = True
            If .ShowDialog = DialogResult.OK Then
                files2List(.FileNames)
            End If
        End With
    End Sub

    Private Sub mostrarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mostrarButton.Click
        ' mostrar el contenido del zip indicado
        Dim files() As ZipEntry = zUtil.Contenido(zipFicTextBox.Text)
        '
        Me.Cursor = Cursors.WaitCursor
        listaFic.Items.Clear()
        '
#If VS2002 Then
        Dim theEntry As ZipEntry
        For Each theEntry In files
            With listaFic.Items.Add(theEntry.Name)
                .SubItems.Add(theEntry.Size.ToString("#,##0"))
            End With
        Next
#Else
        For Each theEntry As ZipEntry In files
            With listaFic.Items.Add(theEntry.Name)
                .SubItems.Add(theEntry.Size.ToString("#,##0"))
            End With
        Next
#End If
        zipButton.Enabled = listaFic.Items.Count > 0
        Me.Cursor = Cursors.Default
    End Sub

    Private Sub zipFicTextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles zipFicTextBox.Enter
        zipFicTextBox.SelectAll()
    End Sub

    Private Sub zipFicTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles zipFicTextBox.TextChanged
        ' si no existe, deshabilitar mostrar
        Try
            mostrarButton.Enabled = IO.File.Exists(zipFicTextBox.Text)
        Catch ex As Exception
            mostrarButton.Enabled = False
        End Try
        unZipButton.Enabled = mostrarButton.Enabled
    End Sub

    Private Sub zipFicTextBox_DragOver(ByVal sender As Object, _
                                       ByVal e As System.Windows.Forms.DragEventArgs) _
                                       Handles zipFicTextBox.DragOver, _
                                               listaFic.DragOver, MyBase.DragOver
        If e.Data.GetDataPresent("FileDrop") = True Then
            e.Effect = DragDropEffects.Copy
        End If
    End Sub

    Private Sub zipFicTextBox_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles zipFicTextBox.DragDrop
        If e.Data.GetDataPresent("FileDrop") = True Then
            zipFicTextBox.Text = CType(e.Data.GetData("FileDrop", True), String())(0)
        End If
    End Sub

    Private Sub listaFic_DragDrop(ByVal sender As Object, _
                                  ByVal e As System.Windows.Forms.DragEventArgs) _
                                  Handles listaFic.DragDrop, MyBase.DragDrop
        If e.Data.GetDataPresent("FileDrop") = True Then
            files2List(CType(e.Data.GetData("FileDrop", True), String()))
        End If
    End Sub

    Private Sub files2List(ByVal files() As String)
        Dim fi As IO.FileInfo
        '
#If VS2002 Then
        Dim s As String
        For Each s In files
            With listaFic.Items.Add(s)
                fi = New IO.FileInfo(s)
                .SubItems.Add(fi.Length.ToString("#,##0"))
            End With
        Next
#Else
        For Each s As String In files
            With listaFic.Items.Add(s)
                fi = New IO.FileInfo(s)
                .SubItems.Add(fi.Length.ToString("#,##0"))
            End With
        Next
#End If
        zipButton.Enabled = listaFic.Items.Count > 0
    End Sub

    Private Sub unZipButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles unZipButton.Click
        ' descomprimir el contenido del fichero en el directorio indicado
        Me.Cursor = Cursors.WaitCursor
        zUtil.Descomprimir(unZipDirTextBox.Text, zipFicTextBox.Text)
        Me.Cursor = Cursors.Default
    End Sub

    Private Sub zipButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles zipButton.Click
        ' comprimir los ficheros de la lista en el zip indicado
        Dim n As Integer = Me.listaFic.Items.Count - 1
        Dim files(n) As String
        '
        Me.Cursor = Cursors.WaitCursor
        '
#If VS2002 Then
        Dim i As Integer
        For i = 0 To n
            files(i) = listaFic.Items(i).Text
        Next
#Else
        For i As Integer = 0 To n
            files(i) = listaFic.Items(i).Text
        Next
#End If
        zUtil.Comprimir(files, zipFicTextBox.Text)
        zipFicTextBox_TextChanged(zipFicTextBox, New EventArgs)
        Me.Cursor = Cursors.Default
    End Sub

    Private Sub examinarDirButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles examinarDirButton.Click
#If VS2002 Then
        ' usar este código para VS2002
        With openFD
            .Title = "Selecciona el directorio para descomprimir los ficheros"
            .Filter = "Todos los ficheros (*.*)|*.*"
            .InitialDirectory = unZipDirTextBox.Text
            .Multiselect = False
            ' para que se puede indicar un fichero que no existe
            .CheckFileExists = False
            If .ShowDialog = DialogResult.OK Then
                unZipDirTextBox.Text = IO.Path.GetDirectoryName(.FileName)
            End If
        End With
#Else
        ' esto sólo es válido para VS2003
        Dim bf As New FolderBrowserDialog
        '
        With bf
            .Description = "Selecciona el directorio para descomprimir los ficheros"
            .RootFolder = Environment.SpecialFolder.MyComputer
            .ShowNewFolderButton = True
            .SelectedPath = unZipDirTextBox.Text
            If .ShowDialog = DialogResult.OK Then
                unZipDirTextBox.Text = .SelectedPath
            End If
        End With
#End If
    End Sub

    Private Sub listaFic_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles listaFic.KeyUp
        ' eliminar los elementos seleccionados
        If e.KeyCode = Keys.Delete Then
            quitarButton_Click(sender, New EventArgs)
        End If
    End Sub

    Private Sub quitarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles quitarButton.Click
        ' eliminar de la lista los elementos seleccionados
        '
#If VS2002 Then
        Dim i As Integer
        For i = listaFic.SelectedIndices.Count - 1 To 0 Step -1
            listaFic.Items.RemoveAt(listaFic.SelectedIndices(i))
        Next
#Else
        For i As Integer = listaFic.SelectedIndices.Count - 1 To 0 Step -1
            listaFic.Items.RemoveAt(listaFic.SelectedIndices(i))
        Next
#End If
        Me.zipButton.Enabled = listaFic.Items.Count > 0
    End Sub
End Class

 


Código para C Sharp (C#)

Aquí tienes los links para las diferentes clases (para C#):

La clase ZipUtil

//------------------------------------------------------------------------------
// ZipUtil                                                           (16/Dic/02)
// utilidad para comprimir/descomprimir ficheros zips
// usando SharpZipLib.dll
//
// ©Guillermo 'guille' Som, 2002
//------------------------------------------------------------------------------
using System;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using System.IO;

public class ZipUtil
{
    public void Comprimir(string directorio, string filtro, string zipFic, bool crearAuto)
    {
        // comprimir los ficheros del directorio indicado
        // y guardarlo en el zip
        // en filtro se indicará el filtro a usar para seleccionar los ficheros del directorio
        // si directorio es una cadena vacía, filtro será el fichero a comprimir (sólo ese)
        // si crearAuto = True, zipfile será el directorio en el que se guardará
        // y se generará automáticamente el nombre con la fecha y hora actual
        //
        string[] fileNames = new string[1];
        if(directorio == "")
        {
            fileNames[0] = filtro;
        }
        else
        {
            fileNames = Directory.GetFiles(directorio, filtro);
        }
        // llamar a la versión sobrecargada que recibe un array
        Comprimir(fileNames, zipFic, crearAuto);
        //
    }  
    //
    public void Comprimir(string[] fileNames, string zipFic, bool crearAuto)
    {
        // comprimir los ficheros del array en el zip indicado
        // si crearAuto = True, zipfile será el directorio en el que se guardará
        // y se generará automáticamente el nombre con la fecha y hora actual
        Crc32 objCrc32 = new  Crc32();
        ZipOutputStream strmZipOutputStream;
        //
        if( zipFic == "" )
        {
            zipFic = ".";
            crearAuto = true;
        }
        if( crearAuto )
        {
            // si hay que crear el nombre del fichero
            // éste será el path indicado y la fecha actual
            zipFic += @"\ZIP" + DateTime.Now.ToString("yyMMddHHmmss") + ".zip";
        }
        strmZipOutputStream = new ZipOutputStream(File.Create(zipFic));
        // Compression Level: 0-9
        // 0: no(Compression)
        // 9: maximum compression
        strmZipOutputStream.SetLevel(6);
        //
        foreach(string strFile in fileNames)
        {
            FileStream strmFile = File.OpenRead(strFile);
            byte[] abyBuffer = new byte[(Convert.ToInt32(strmFile.Length))];
            //
            strmFile.Read(abyBuffer, 0, abyBuffer.Length);
            //
//              //-------------------------------------------------------------
//              // para guardar sin el primer path
//              string sFile = strFile;
//              int i = sFile.IndexOf(@"\");
//              if( i > -1)
//              {
//                  sFile = sFile.Substring(i + 1).TrimStart();
//              }
//              //-------------------------------------------------------------
//              //
//              //-------------------------------------------------------------
//              // para guardar sólo el nombre del fichero
//              // esto sólo se debe hacer si no se procesan directorios
//              // que puedan contener nombres repetidos
//              string sFile = Path.GetFileName(strFile);
//              ZipEntry theEntry = new ZipEntry(sFile);
//              //-------------------------------------------------------------
            //
            // se guarda con el path completo
            ZipEntry theEntry  = new ZipEntry(strFile);
            //
            // guardar la fecha y hora de la última modificación
            FileInfo fi = new FileInfo(strFile);
            theEntry.DateTime = fi.LastWriteTime;
            //theEntry.DateTime = DateTime.Now;
            //
            theEntry.Size = strmFile.Length;
            strmFile.Close();
            objCrc32.Reset();
            objCrc32.Update(abyBuffer);
            theEntry.Crc = objCrc32.Value;
            strmZipOutputStream.PutNextEntry(theEntry);
            strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length);
        }
        strmZipOutputStream.Finish();
        strmZipOutputStream.Close();
    }  
    //
    public void Descomprimir(string directorio, string zipFic, bool eliminar, bool renombrar)
    {
        // descomprimir el contenido de zipFic en el directorio indicado.
        // si zipFic no tiene la extensión .zip, se entenderá que es un directorio y
        // se procesará el primer fichero .zip de ese directorio.
        // si eliminar es True se eliminará ese fichero zip después de descomprimirlo.
        // si renombrar es True se añadirá al final .descomprimido
        if( !zipFic.ToLower().EndsWith(".zip") )
        {
            zipFic = Directory.GetFiles(zipFic, "*.zip")[0];
        }
        // si no se ha indicado el directorio, usar el actual
        if( directorio == "" ) directorio = ".";
        //
        ZipInputStream z = new  ZipInputStream(File.OpenRead(zipFic));
        ZipEntry theEntry;
        //
        do
        {
            theEntry = z.GetNextEntry();
            if( !(theEntry == null) )
            {
                string fileName = directorio + @"\" + Path.GetFileName(theEntry.Name);
                //
                // dará error si no existe el path
                FileStream streamWriter;
                try
                {
                    streamWriter = File.Create(fileName);
                }
                catch (DirectoryNotFoundException ex)
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(fileName));
                    streamWriter = File.Create(fileName);
                }
            //
            int size = 2048;
            byte[] data = new byte[2048];
            do
            {
                size = z.Read(data, 0, data.Length);
                if( (size > 0) )
                {
                    streamWriter.Write(data, 0, size);
                }
                else
                {
                    break;
                }
            }while(true);
            streamWriter.Close();
        }
        else
        {
            break;
        }
        }while(true);
            z.Close();
            //
            // cuando se hayan extraído los ficheros, renombrarlo
            if( renombrar )
            {
                File.Copy(zipFic, zipFic + ".descomprimido");
            }
        if( eliminar )
        {
            File.Delete(zipFic);
        }
    }  
    //
    public ZipEntry[] Contenido(string zipFic)
    {
        // devuelve el contenido del zip indicado
        ZipInputStream strmZipInputStream = new ZipInputStream(File.OpenRead(zipFic));
        ZipEntry objEntry;
        ZipEntry[] files = new ZipEntry[1];
        int n  = -1;
        //
        while ((objEntry = strmZipInputStream.GetNextEntry()) != null)
        {
            n = n + 1;
            // hacer una copia de files
            // para añadir el nuevo elemento
            // ¡con lo fácil que es usar ReDim Preserve!
            if(n > 0)
            {
                ZipEntry[] files2 = new ZipEntry[n + 1];
                Array.Copy(files, files2, n);
                files2[n] = objEntry;
                files = new ZipEntry[n + 1];
                Array.Copy(files2, files, n + 1);
                files2 = null;
            }
            else
            {
                files[0] = objEntry;
            }
        }
        strmZipInputStream.Close();
        //
        return files;
    }  
}
 

La clase cLine3DEx

//------------------------------------------------------------------------------
// cLine3DEx para vb.NET                                             (19/Nov/01)
//
// xShadowLine                                                       (29/Ago/98)
// Line3DEx Nuevo nombre y nuevas propiedades                        (16/Ene/99)
//
// Un control MUY simple para simular líneas sombreadas (3D)
//
//
// ©Guillermo 'guille' Som, 1998-2002
//------------------------------------------------------------------------------
using System;
using System.Drawing;   
using System.Windows.Forms;

namespace tSharpZipLibCS
{
public class cLine3DEx{
    private bool m_Inset  = true;
    //
    private System.Drawing.Color ColorOscuro = Color.FromKnownColor(KnownColor.ControlDark);
    private System.Drawing.Color ColorClaro  = Color.FromKnownColor(KnownColor.ControlLightLight);
    //
    // Si se ajusta automáticamente al ancho del contenedor
    private bool m_AdjustWidth;
    // Separación desde la izquierda del borde del contenedor        (18/Ene/99)
    // (este mismo valor se aplica a la derecha)
    private int m_IndentValue;
    // Variables para las dos etiquetas que se usarán
    private Label[] mLine1 = new Label[2];
    // Contenedor de las etiquetas
    private ContainerControl mContenedor;
    // Posición de la línea
    private int mLeft;
    private int mWidth;
    //
    public cLine3DEx(Label Label1, Label Label2, ContainerControl Contenedor) : base()
    {
        m_Inset = true;
        m_AdjustWidth = false;
        m_IndentValue = 4;
        mContenedor = Contenedor;
        mLine1[0] = Label1;
        mLine1[1] = Label2;
        mLine1[1].SendToBack();
        mLine1[0].BackColor = ColorOscuro;
        mLine1[0].Height = 1;
        mLine1[0].Left = m_IndentValue;
        //
        mLine1[1].BackColor = ColorClaro;
        mLine1[1].Height = 1;
        mLine1[1].Top = mLine1[0].Top + 1;
        mLine1[1].Left = m_IndentValue;
    }  
    //
    public bool  AdjustWidth{
        get{
            return m_AdjustWidth;
        }
        set{
            // Si se ajusta automáticamente al ancho del contenedor
            m_AdjustWidth = value;
            UserControl_Resize();
        }
    }  
    //
    public int IndentValue
    {
        get{
            return m_IndentValue;
        }
        set{
            m_IndentValue = value;
            // Reajustar el tamaño de las líneas
            UserControl_Resize();
        }
    }  
    //
    public bool Inset
    {
        get{
            return m_Inset;
        }
        set{
            m_Inset = value;
            UserControl_Resize();
        }
    }  
    //
    public bool Raised
    {
        get{
            return m_Inset;
        }
        set{
            m_Inset = !value;
            UserControl_Resize();
        }
    }  
    //
    public void Resize()
    {
        // Método para ajustar el tamaño de las líneas
        // normalmente se usará en el evento Resize del contenedor
        UserControl_Resize();
    }  
    private void UserControl_Resize()
    {
        //
        // Si se debe ajustar automáticamente al ancho del contenedor
        if( m_AdjustWidth )
        {
            mLeft = 0;
            // Si se especifica el valor de indentación
            mLeft += m_IndentValue;
            mWidth = mContenedor.DisplayRectangle.Width - (mLeft * 2);
        }
        //
        if( m_Inset )
        {
            mLine1[0].BackColor = ColorOscuro;
        }
        else
        {
            mLine1[0].BackColor = ColorClaro;
        }
        mLine1[0].Width = mWidth;
        mLine1[0].Left = mLeft;
        //
        if( m_Inset )
        {
            mLine1[1].BackColor = ColorClaro;
            mLine1[1].BringToFront();
        }
        else
        {
            mLine1[1].BackColor = ColorOscuro;
            mLine1[1].SendToBack();
        }
        mLine1[1].Width = mWidth;
        mLine1[1].Left = mLeft;
    }  
}	
}

El formulario de ejemplo

//------------------------------------------------------------------------------
// Utilidad para comprimir/descomprimir ficheros                     (16/Dic/02)
// usando SharpZipLib.dll
//
// ©Guillermo 'guille' Som, 2002
//------------------------------------------------------------------------------
// En este ejemplo utilizo esta constante para indicar si el código
// es compatible con el VS 2002 o para versiones posteriores
// En el caso de las versiones posteriores, se usan los bucles
// con la variable declarada junto al For o ForEach y
// para seleccionar directorios se usa la nueva clase FolderBrowserDialog
#define VS2002

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

/// 
/// Descripción breve de Form1.
/// 
public class fZipTest : System.Windows.Forms.Form
{
    //
    //...
    //
    private bool iniciando = true;
    private cLine3DEx linea3D;
    private OpenFileDialog openFD = new OpenFileDialog();
    private ZipUtil zUtil = new ZipUtil();
    //
    private void fZipTest_Load(System.Object  sender, System.EventArgs  e) 
    {
        linea3D = new cLine3DEx(linea1, linea2, this);
        linea3D.AdjustWidth = true;
        //
        zipFicTextBox.Text = "";
        unZipDirTextBox.Text = "";
        zipButton.Enabled = false;
        //
        iniciando = false;
    }  

    private void fZipTest_Resize(object  sender, System.EventArgs  e) 
    {
        if( !iniciando )
        {
            if( WindowState != FormWindowState.Minimized )
            {
                linea3D.Resize();
            }
        }
    }  

    private void cerrarButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        this.Close();
    }  

    private void examinarButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // seleccionar el fichero ZIP con el que se va a trabajar
        openFD.Title = "Selecciona el fichero ZIP";
        openFD.Filter = "Ficheros ZIPs (*.zip)|*.zip|Todos los ficheros (*.*)|*.*";
        openFD.FileName = this.zipFicTextBox.Text;
        openFD.Multiselect = false;
        // para que se puede indicar un fichero que no existe
        openFD.CheckFileExists = false;
        if( openFD.ShowDialog() == DialogResult.OK )
        {
            zipFicTextBox.Text = openFD.FileName;
        }

    }  

    private void addButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // añadir ficheros a la lista
        openFD.Title = "Selecciona los ficheros a comprimir";
        openFD.Filter = "Código|*.vb*;*.c*;*.pas;*.h*;*.bas;*.pr*;|Todos los ficheros (*.*)|*.*";
        openFD.Multiselect = true;
        if( openFD.ShowDialog() == DialogResult.OK )
        {
            files2List(openFD.FileNames);
        }

    }  

    private void mostrarButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // mostrar el contenido del zip indicado
        ZipEntry[] files = zUtil.Contenido(zipFicTextBox.Text);
        //
        this.Cursor = Cursors.WaitCursor;
        listaFic.Items.Clear();
        //
        foreach(ZipEntry theEntry in files)
        {
            if(theEntry != null)
            {
                ListViewItem lvi = listaFic.Items.Add(theEntry.Name);
                lvi.SubItems.Add(theEntry.Size.ToString("#,##0"));
            }
        }
        zipButton.Enabled = listaFic.Items.Count > 0;
        this.Cursor = Cursors.Default;
    }  

    private void zipFicTextBox_Enter(object  sender, System.EventArgs  e) 
    {
        zipFicTextBox.SelectAll();
    }  

    private void zipFicTextBox_TextChanged(System.Object  sender, System.EventArgs  e) 
    {
        // si no existe, deshabilitar mostrar
        try
        {
            mostrarButton.Enabled = File.Exists(zipFicTextBox.Text);
        }
        catch //(Exception ex )
        {

            mostrarButton.Enabled = false;
        }
        unZipButton.Enabled = mostrarButton.Enabled;
    }  

    private void zipFicTextBox_DragOver(object  sender, System.Windows.Forms.DragEventArgs  e)
    { // 
        if( e.Data.GetDataPresent("FileDrop") == true )
        {
            e.Effect = DragDropEffects.Copy;
        }
    }  

    private void zipFicTextBox_DragDrop(object  sender, System.Windows.Forms.DragEventArgs  e) 
    {
        if( e.Data.GetDataPresent("FileDrop") == true )
        {
            zipFicTextBox.Text = ((string[])(e.Data.GetData("FileDrop", true)))[0];         }
    }  

    private void listaFic_DragDrop(object  sender, System.Windows.Forms.DragEventArgs  e)
    {
        if( e.Data.GetDataPresent("FileDrop") == true )
        {
            files2List(( (string[])(e.Data.GetData("FileDrop", true)) ));
        }
    }  

    private void files2List(string[] files)
    {
        FileInfo fi;
        //
        foreach(string s in files)
        {
            fi = new FileInfo(s);
            listaFic.Items.Add(s).SubItems.Add(fi.Length.ToString("#,##0"));

        }
        zipButton.Enabled = listaFic.Items.Count > 0;
    }  

    private void unZipButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // descomprimir el contenido del fichero en el directorio indicado
        this.Cursor = Cursors.WaitCursor;
        zUtil.Descomprimir(unZipDirTextBox.Text, zipFicTextBox.Text, false, false);
        this.Cursor = Cursors.Default;
    }  

    private void zipButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // comprimir los ficheros de la lista en el zip indicado
        int n  = this.listaFic.Items.Count - 1;
        string[] files = new string[(n + 1)];
        //
        this.Cursor = Cursors.WaitCursor;
        //
        for(int i = 0; i <= n; i++)
        {
            files[i] = listaFic.Items[i].Text;
        }
        zUtil.Comprimir(files, zipFicTextBox.Text, false);
        zipFicTextBox_TextChanged(zipFicTextBox, new EventArgs());
        this.Cursor = Cursors.Default;
    }  

    private void examinarDirButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // usar este código para VS2002
        openFD.Title = "Selecciona el directorio para descomprimir los ficheros";
        openFD.Filter = "Todos los ficheros (*.*)|*.*";
        openFD.InitialDirectory = unZipDirTextBox.Text;
        openFD.Multiselect = false;
        // para que se puede indicar un fichero que no existe
        openFD.CheckFileExists = false;
        if( openFD.ShowDialog() == DialogResult.OK )
        {
            unZipDirTextBox.Text = Path.GetDirectoryName(openFD.FileName);
        }
//          //
//          // esto sólo es válido para VS2003
//          //
//          FolderBrowserDialog bf = new  FolderBrowserDialog();
//          //
//          bf.Description = "Selecciona el directorio para descomprimir los ficheros";
//          bf.RootFolder = Environment.SpecialFolder.MyComputer;
//          bf.ShowNewFolderButton = true;
//          bf.SelectedPath = unZipDirTextBox.Text;
//          if( bf.ShowDialog == DialogResult.OK ){
//              unZipDirTextBox.Text = bf.SelectedPath;
//          }
//          //
//          //
//          //
    }  

    private void listaFic_KeyUp(object  sender, System.Windows.Forms.KeyEventArgs  e) 
    {
        // eliminar los elementos seleccionados
        if( e.KeyCode == Keys.Delete )
        {
            quitarButton_Click(sender, new EventArgs());
        }
    }  

    private void quitarButton_Click(System.Object  sender, System.EventArgs  e) 
    {
        // eliminar de la lista los elementos seleccionados
        //
        for(int i = listaFic.SelectedIndices.Count - 1; i >= 0; i--)
        {
            listaFic.Items.RemoveAt(listaFic.SelectedIndices[i]);
        }
        this.zipButton.Enabled = listaFic.Items.Count > 0;
    }  
}
 

la Luna del Guille o... el Guille que está en la Luna... tanto monta...