Code Master38 Ответов: 3

DotNetZip Помочь Прогрессу


По какой-то причине, когда я пытаюсь распаковать zip-файл, он не обновляет индикатор выполнения, любая помощь будет приветствоваться.

Imports Ionic.Zip
Imports System.Threading

Public Class Form1

    Private Property CurrentCount As Integer
    Private Property TotalCount As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

    Private Delegate Sub SetStatusTextInvoker(ByVal Text As String)
    Private Sub SetStatusText(ByVal Text As String)
        If Me.InvokeRequired Then
            Me.Invoke(New SetStatusTextInvoker(AddressOf SetStatusText), Text)
        Else
            Label1.Text = Text
        End If
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim TotalSize As Long
        Dim ZipToUnpack As String = "C:\temp\1.zip"
        Dim extractDir As String = "C:\temp\extract"

        Try
            Using zip As ZipFile = ZipFile.Read(ZipToUnpack)
                AddHandler (zip.ExtractProgress), New EventHandler(Of ExtractProgressEventArgs)(AddressOf Zip_ExtractProgress)

                For Each Entry As ZipEntry In zip.Entries
                    TotalSize += Entry.UncompressedSize
                Next
                For Each Entry As ZipEntry In zip.Entries
                    Entry.Extract(extractDir, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
                Next
            End Using
        Catch EX As Exception
            MessageBox.Show(EX.Message)
        End Try
    End Sub

    Private Sub Zip_ExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
        If BackgroundWorker1.CancellationPending Then
            e.Cancel = True 'If we press the stop button, reset the variables we used for extracting, then invoke Cancel. RunWorkerCompleted will be called.
        End If

        Select Case e.EventType
            Case ZipProgressEventType.Extracting_EntryBytesWritten

                Dim Entry As Integer
                Dim CurrentCount As Integer = Entry
    
                BackgroundWorker1.ReportProgress(CInt(Int((100 * (CurrentCount / TotalCount)))))
        End Select
    End Sub
End Class

3 Ответов

Рейтинг:
2

Christian Graus

Вы установили точку останова, чтобы узнать, вызывается ли она ? Если это так,вы можете попробовать приложение.DoEvents, если проблема заключается только в том, что требуется событие paint.


Рейтинг:
0

Florin Pănescu

Попробуйте этот код и посмотрите, поможет ли он вам, я использую только один ProgressBar.

Imports Ionic.Zip
Imports System.Threading
Imports System.IO


Public Class Form1

    Private CurrentCount As Integer = 0
    Private TotalCount As Long = 0, Total As Long = 0, LastVal As Long = 0, Sum As Long = 0


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        ProgressBar1.Maximum = CInt(TotalCount)
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

    Private Delegate Sub SetStatusTextInvoker(ByVal Text As String)
    Private Sub SetStatusText(ByVal Text As String)
        System.Threading.Thread.Sleep(6)
        If Me.InvokeRequired Then
            Me.Invoke(New SetStatusTextInvoker(AddressOf SetStatusText), Text)
        Else
            Label1.Text = Text
        End If
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ExtractZip("C:\test\test.zip", "C:\test\extract\")
    End Sub

    Public Sub ExtractZip(ByVal szFileZip As String, ByVal ExtractTo As String)

        ' This will delete temp file when you cancel the extraction.
        Dim szGetFiles As Collections.ObjectModel.ReadOnlyCollection(Of String)
        Dim FilePath As String
        szGetFiles = My.Computer.FileSystem.GetFiles("C:\test\", FileIO.SearchOption.SearchAllSubDirectories, "*.tmp")
        For Each FilePath In szGetFiles
            File.Delete(FilePath)
        Next
        Try
            CurrentCount = 0
            Using MyZip As ZipFile = ZipFile.Read(szFileZip)
                AddHandler (MyZip.ExtractProgress), New EventHandler(Of ExtractProgressEventArgs)(AddressOf Zip_ExtractProgress)
                For Each Entry As ZipEntry In MyZip
                    CurrentCount += 1
                    TotalCount += Entry.UncompressedSize
                Next Entry
                MyZip.ExtractAll(ExtractTo, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
            End Using
        Catch ex As Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub Zip_ExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
        If BackgroundWorker1.CancellationPending Then
            e.Cancel = True 'If we press the stop button, reset the variables we used for extracting, then invoke Cancel. RunWorkerCompleted will be called.
        End If
        System.Windows.Forms.Application.DoEvents()
        If Total <> e.TotalBytesToTransfer Then
            SetStatusText(e.CurrentEntry.FileName)
            Sum += Total - LastVal + e.BytesTransferred
            Total = e.TotalBytesToTransfer
        Else
            Sum += e.BytesTransferred - LastVal
        End If
        LastVal = e.BytesTransferred
        BackgroundWorker1.ReportProgress(CInt((Sum)))
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ProgressBar1.Value = 0
        SetStatusText("Completed")
    End Sub
End Class


Blutfaust

Так вы думаете, что то все еще ждет решения? Через 1,5 года?

Florin Pănescu

@Blutfaust вы правы, это мой первый ответ здесь, может быть, это решение для него больше не важно, но, может быть, для других людей, которые ищут это решение, важно.
Извините за мой плохой английский.

Рейтинг:
0

Bart Van Eyndhoven

Привет,

Может быть, немного поздно, но у меня все получилось довольно легко.

Прежде всего, я бы предложил переписать вашу строку обработчика событий следующим образом:

AddHandler MyZip.ExtractProgress, AddressOf Zip_ExtractProgress
Вы просто хотите указать событие на субмарину Zip_ExtractProgress.

Затем вам нужно будет определить тип подробной информации, предоставляемой событием.

Так вы бы и сделали:

Private Sub Extract_Zipfile(ByVal sourcePath As String, ByVal targetPath as String)
    Dim fileToExtract as ZipFile

    fileToExtract = ZipFile.Read(sourcePath)
    With fileToExtract
        .UseUnicodeAsdNecessary = True 'To extract files with unicode chars
        AddHandler .ExtractProgress, AddressOf Zip_ExtractProgress 'The new addhandler mentioned above

        'Write code to prefetch some info, like the total uncompressed size.
        'You won't need to calculate the number of files, just use fileToExtract.Entries.Count

        'The actual extracting
        fileToExtract.ExtractAll(ExtractTo, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
    End With
End Sub

Private Sub Zip_ExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
    'You'll have to experiment somewhat using the smart suggest lists...
    If e.EventType = ZipProgressEventType.Extracting_BeforeExtractEntry then
        'Update your labels, progress bars, ...
        pgbFileExtractProgress.Maximum = 100
        'Better calculate the progressbar value.
        pgbFileExtractProgress.Value = Convert.ToInt16((e.BytesTransferred / e.TotalBytesToTransfer)*

    'Use a couple of ElseIfs to catch other kinds of events
    End If

    Application.DoEvents() 'Allows your forms to display the updated values.
End Sub
Это должно сработать...


Dave Kreskowiak

4 года-это "немного поздно"?