Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.65/99: Рейтинг темы: голосов - 99, средняя оценка - 4.65
51 / 51 / 7
Регистрация: 23.01.2012
Сообщений: 449
1

DotNetZip разархивирование с ProgressBar

06.03.2012, 18:44. Показов 17873. Ответов 37
Метки нет (Все метки)

Всем хорошего настроения


Я с вопросами.

Работаю с DotNetZip, который позволяет распаковывать-упаковывать архивы.

Распаковка:

C#
1
2
3
4
5
6
7
                    string zep = @"D:\es\rzip.zip";
                    string raz = @"D:\es\";
 
                    using (ZipFile zip = ZipFile.Read(zep))
                    {
                        zip.ExtractAll(raz);
                    }
И сам вопрос: Как процесс распаковки выводить в ProgressBar ?

Пробовал вот так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ionic.Zip;
using System.Threading;
using Microsoft.Win32;
using System.IO;
using test.saic.library;
using CTSDBExtractionApp.StringExtentions;
 
 
namespace CTSDB
{
    public partial class FormProgress : Form
    {
 
        private BackgroundWorker _zipBGWorker;
        private delegate void ZipProgressEventHandler(ExtractProgressEventArgs e);
        private delegate void ExtractEntryProgressEventHandler(ExtractProgressEventArgs e);
 
        public string ExtractPath { get; set; }
 
        // Disable User Closing Form
        private bool AllowClose = false;
 
        public FormProgress()
        {
            InitializeComponent();
            SetTitle();
        }
 
        private void SetTitle()
        {
            this.Text = "CTS Database Decompression";
        }
 
        private void GetMSSQLPath()
        {
            string sKey = "Software\\Microsoft\\Microsoft SQL Server\\CTSDB\\Setup";
            RegistryKey rk = Registry.LocalMachine;
 
            try
            {
                RegistryKey sk1 = rk.OpenSubKey(sKey);
 
                string sVal = (string)sk1.GetValue("SQLPath");
                if (sVal == null)
                {
                    MessageBox.Show("Registry value " + sKey + " not set.",
                                    "CTS Database Extraction", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
 
                int iVal;
                bool bConverted = Int32.TryParse(sVal.Right(1), out iVal);
                if (bConverted && iVal == 0)
                {
                    ExtractPath = sVal.Left(sVal.Length - 1) + "\\Data";
                }
                else
                {
                    ExtractPath = sVal + "\\Data";
                }
 
            }
            catch (Exception e)
            {
                MessageBox.Show("Unable to open key " + sKey + ": " + e.Message,
                                "CTS Database Extraction", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            GetMSSQLPath();
            DoExtract("Cdrsqlbs.zip");
        }
 
        private void DoExtract(string ZipToExtract)
        {
            object[] args = new object[3];
            args[0] = ZipToExtract;
            args[1] = ExtractPath;
            _zipBGWorker = new BackgroundWorker();
            _zipBGWorker.WorkerSupportsCancellation = true;
            _zipBGWorker.WorkerReportsProgress = false;
            _zipBGWorker.DoWork += new DoWorkEventHandler(_zipBGWorker_DoWork);
            _zipBGWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_zipBGWorker_RunWorkerCompleted);
            _zipBGWorker.RunWorkerAsync(args);
            this.Cursor = Cursors.WaitCursor;
        }
 
        void _zipBGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Close();
        }
 
        private void _zipBGWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] args = (object[])e.Argument;
            var list = args.Cast<string>().ToList();
            string ZipToUnpack = list[0];
            string extractDir = list[1];
 
            try
            {
                using (ZipFile zip = ZipFile.Read(ZipToUnpack))
                {
                    SetProgressBarMax(zip.Entries.Count);
                    zip.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress);
                    zip.ExtractAll(extractDir, ExtractExistingFileAction.OverwriteSilently);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("There's been a problem extracting that zip file.  {0}", ex.Message), 
                       "Error Extracting", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }
        }
 
        void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
        {
            if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
            {
                StepEntryProgress(e);
            }
        }
 
        private void SetProgressBarMax(int n)
        {
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new Action<int>(SetProgressBarMax), new object[] { n });
            }
            else
            {
                progressBar1.Maximum = n;
                progressBar1.Step = 1;
            }
        }
 
        private void StepEntryProgress(ExtractProgressEventArgs e)
        {
 
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new ExtractEntryProgressEventHandler(this.StepEntryProgress), new object[] { e });
            }
            else
            {
                progressBar1.Maximum = 100;
                progressBar1.Value = Convert.ToInt32(100 * e.BytesTransferred / e.TotalBytesToTransfer);
            }
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing && AllowClose)
            {
                e.Cancel = true;
            }
        }
 
        public void ForceClose()
        {
            AllowClose = true;
            this.Close();
            AllowClose = false;
        }
 
     }
}
Не получилось.....

Как вывести процесс распаковки в ProgressBar ?

Спасибо заранее)))

0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.03.2012, 18:44
Ответы с готовыми решениями:

DotNetZip распаковка с прогрессом
Здравствуйте! Необходима ваша помощь! Пытаюсь сделать распаковку архива с прогресс баром но нифига...

Распаковка .zip (DotNetZip)
Не могу программно распаковать архив, вылетают 2 разных исключения. Пользуюсь библиотекой DotNetZip...

Разархивирование
Здравствуйте. Помогите, плиз. Есть папка D:\RAR. в ней много архивов. Как разархивировать их в...

Разархивации каталога библиотекой DotNetZip
Добрый вечер, дорогие гуру. Решил написать программу для разархивации каталога. Вот сама функция:...

37
Эксперт С++
2357 / 1976 / 287
Регистрация: 03.05.2011
Сообщений: 4,396
Записей в блоге: 13
06.03.2012, 18:59 2
используете BackgroundWorker http://msdn.microsoft.com/ru-r... orker.aspx
C#
1
2
3
4
5
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text = "Progress: " + e.ProgressPercentage.ToString() + "%";
            progressBar1.Value = e.ProgressPercentage;
        }
самое простое решение.
2
51 / 51 / 7
Регистрация: 23.01.2012
Сообщений: 449
06.03.2012, 19:09  [ТС] 3
Цитата Сообщение от _lunar_ Посмотреть сообщение
самое простое решение.

Как вызвать ? из:
C#
1
2
3
4
                    using (ZipFile zip = ZipFile.Read(zep))
                    {
                        zip.ExtractAll(raz);
                    }
0
Эксперт С++
2357 / 1976 / 287
Регистрация: 03.05.2011
Сообщений: 4,396
Записей в блоге: 13
06.03.2012, 19:26 4
в кнопке, которая запускает процесс распаковки (или то, что запускает)
C#
1
backgroundWorker1.RunWorkerAsync();
это запустит DoWork
C#
1
2
3
4
5
6
7
8
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {   
             using (ZipFile zip = ZipFile.Read(zep))
                    {
                        zip.ExtractAll(raz);
                    }
             // сюда всё что связано с распаковкой
        }
если DoWork запущен происходит WorkerReportsProgress
C#
1
2
3
4
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
1
51 / 51 / 7
Регистрация: 23.01.2012
Сообщений: 449
06.03.2012, 19:44  [ТС] 5
Цитата Сообщение от _lunar_ Посмотреть сообщение
это запустит DoWork
Не получилось сделать, так как процесс распаковка в отдельной функции.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        private void ziip(string zep, string raz)
        {
            try
            {
                    using (ZipFile zip = ZipFile.Read(zep))
                    {
                        zip.ExtractAll(raz);
                    }
            }
            catch (Exception)
            {
                process.Text = "ОШИБКА";
            }
        }
0
Почетный модератор
Эксперт .NET
8699 / 3651 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.03.2012, 22:27 6
Лучший ответ Сообщение было отмечено как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/* button1 - кнопка при нажатии на которую запускается распаковка
 * progressBar1 - отображает процесс распаковки
 */
 
SynchronizationContext context;
 
private void button1_Click ( object sender, System.EventArgs e )
{
    var zip = ZipFile.Read( @"F:\processhacker-2.26-src.zip" );
    zip.ExtractProgress += zip_ExtractProgress;
    progressBar1.Maximum = zip.Count;
 
    context = SynchronizationContext.Current;
    new Thread(
        delegate( ) {
            ExtractAsync( @"F:\temp\trash\DotNetZipLib0", zip );
        } ).Start();
}
/// <summary>
/// Метод распаковки всех файлов в указанную папку.
/// </summary>
/// <param name="to">Папка в которую будет распакован архив.</param>
/// <param name="zip">Экземпляр класса ZipFile, из которого нужно произвести распаковку.</param>
void ExtractAsync ( string to, ZipFile zip )
{
    zip.ExtractAll( to, ExtractExistingFileAction.OverwriteSilently );
    zip.Dispose();
}
 
void zip_ExtractProgress ( object sender, ExtractProgressEventArgs e )
{
    switch ( e.EventType )
    {
    case ZipProgressEventType.Extracting_AfterExtractEntry:
        if ( context != null )
            context.Send(
                ( o ) => {
                    // --->
                    button1.Text = string.Format( 
                        "{0} from {1}", 
                        e.EntriesExtracted, 
                        e.EntriesTotal 
                        );
                    progressBar1.Value = e.EntriesExtracted;
                    // <---
                },
                null
                );
        break;
    }
}
5
51 / 51 / 7
Регистрация: 23.01.2012
Сообщений: 449
07.03.2012, 17:15  [ТС] 7
Большое спасибо. Очень благодарен!
0
2 / 2 / 0
Регистрация: 11.04.2012
Сообщений: 5
11.04.2012, 15:45 8
Доброго времени суток!

Хотелось бы еще спросить как можно с помощью компонента progressBar выводить состояние архивации папки:

C#
1
2
3
ZipFile zip = new ZipFile(Encoding.UTF8);
zip.AddDirectory(dir);
zip.Save("Archive.zip");
Ps: Можно, если так конечно проще, через количество упаковываемых файлов, т.к. в моем случае размеры файлов малы и приблизительно равны.
0
0 / 0 / 0
Регистрация: 23.04.2012
Сообщений: 3
23.04.2012, 15:46 9
Нашел стстью, как сделать процесс бар на архивирование штатными средствами библиотеки:
http://www.whitebyte.info/prog... -dotnetzip

если ссылка не работает, ниже привожу код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private void buttonCompress_Click(object sender, EventArgs e)
{
    if ((folderBrowserDialog1.ShowDialog() == DialogResult.OK) &amp;&amp; (saveFileDialog1.ShowDialog() == DialogResult.OK))
    {
        buttonCompress.Enabled = false;
 
        String DirectoryToZip = folderBrowserDialog1.SelectedPath;
        String ZipFileToCreate = saveFileDialog1.FileName;
 
        using (ZipFile zip = new ZipFile())
        {
            zip.CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
            zip.SaveProgress += SaveProgress;
 
            zip.StatusMessageTextWriter = System.Console.Out;
            zip.AddDirectory(DirectoryToZip); // recurses subdirectories
            zip.Save(ZipFileToCreate);
        }
    }
}
 
public void SaveProgress(object sender, SaveProgressEventArgs e)
{
    if (e.EventType == ZipProgressEventType.Saving_Started)
    {
        MessageBox.Show("Begin Saving: " + e.ArchiveName);
    }
    else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
    {
        labelCompressionStatus.Text = "Writing: " + e.CurrentEntry.FileName + " (" + (e.EntriesSaved + 1) + "/" + e.EntriesTotal + ")";
        labelFilename.Text = "Filename:" + e.CurrentEntry.LocalFileName;
 
        progressBar2.Maximum = e.EntriesTotal;
        progressBar2.Value = e.EntriesSaved + 1;
    }
    else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
    {
        progressBar1.Value = (int)((e.BytesTransferred * 100) / e.TotalBytesToTransfer);
    }
    else if (e.EventType == ZipProgressEventType.Saving_Completed)
    {
        MessageBox.Show("Done: " + e.ArchiveName);
    }
}
Сам воспользовался данным примером, всё работает
0
2 / 2 / 0
Регистрация: 11.04.2012
Сообщений: 5
23.04.2012, 18:11 10
C#
1
zip.SaveProgress += SaveProgress;
- vs орет на эту строку: "Ошибка 1 Для нестатического поля, метода или свойства "zip_archive.Form1.SaveProgress(object, Ionic.Zip.SaveProgressEventArgs)" требуется ссылка на объект C:\Documents and Settings\<user>\Мои документы\Visual Studio 2010\Projects\zip_archive\zip_archive\Form1.cs 37 37 zip_archive"

Есть мысли, что не так?
0
Эксперт Java
4075 / 3809 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
24.04.2012, 08:27 11
Цитата Сообщение от Dezmond_12 Посмотреть сообщение
C#
1
zip.SaveProgress += SaveProgress;
- vs орет на эту строку: "Ошибка 1 Для нестатического поля, метода или свойства "zip_archive.Form1.SaveProgress(object, Ionic.Zip.SaveProgressEventArgs)" требуется ссылка на объект C:\Documents and Settings\<user>\Мои документы\Visual Studio 2010\Projects\zip_archive\zip_archive\Form1.cs 37 37 zip_archive"

Есть мысли, что не так?
У вас эта строка находится в статическом методе, а вы указываете ссылку на нестатический метод.
Либо делайте SaveProgress статическим, либо указывайте объект, перед именем метода.
1
2 / 2 / 0
Регистрация: 11.04.2012
Сообщений: 5
24.04.2012, 09:53 12
turbanoff, вот я олень, забыл же, что в отдельном потоке архивацию пускаю...

Всем спасибо, все робит!
0
1 / 1 / 2
Регистрация: 07.01.2012
Сообщений: 195
03.05.2012, 11:25 13
Здравия, не буду плодить новые темы, т.к. темматика вопроса похожая. Сам чайник, поэтому не бейте сильно
Скачал я DotNetZip, а как его поставить? Какой файл переносить в Обозреватель решений? Мне нужно разархивировать архив в папку.
0
Миниатюры
DotNetZip разархивирование с ProgressBar  
2 / 2 / 0
Регистрация: 11.04.2012
Сообщений: 5
03.05.2012, 11:35 14
Скачиваешь с сайта архив. Находишь в нем файл Ionic.Zip.dll. Копируешь его в папку с проектом. Потом запускаешь проект, в обозревателе решений щелкаешь правой кнопкой на "ссылки" -> добавить ссылку. Во вкладке обзор находишь файл библиотеки(Ionic.Zip.dll). Потом дописываешь
C#
1
using Ionic.Zip;
1
1 / 1 / 2
Регистрация: 07.01.2012
Сообщений: 195
03.05.2012, 13:17 15
Спасибо, разобрался.

Добавлено через 1 час 25 минут
А можно ли как-то программно заменить то, что в папке на то, что было в архиве? А то с таким кодом он не меняет:
C#
1
 zip.ExtractAll(@"" + path + "Image");
0
2 / 2 / 0
Регистрация: 11.04.2012
Сообщений: 5
03.05.2012, 13:29 16
Ну вообще можно распаковать с заменой можно так:
C#
1
2
3
4
5
6
7
using (ZipFile zip = new ZipFile("Archive.zip", Encoding.UTF8))
            {
                foreach (ZipEntry ext in zip)
                {
                    ext.Extract(unpackDir, ExtractExistingFileAction.OverwriteSilently);
                }
            }
Это заменит все файлы с таким же именем. Если же в папке есть еще какие-то файлы то предварительнь очисти/удали папку, например так:
C#
1
2
DirectoryInfo di = new DirectoryInfo(@"C:\WINNT");
di.Delete(true);
1
1 / 1 / 2
Регистрация: 07.01.2012
Сообщений: 195
03.05.2012, 13:33 17
Хм, не выходит.
0
Миниатюры
DotNetZip разархивирование с ProgressBar   DotNetZip разархивирование с ProgressBar  
28 / 23 / 8
Регистрация: 25.10.2009
Сообщений: 249
11.04.2013, 19:05 18
Цитата Сообщение от _lunar_ Посмотреть сообщение
в кнопке, которая запускает процесс распаковки (или то, что запускает)
C#
1
backgroundWorker1.RunWorkerAsync();
это запустит DoWork
C#
1
2
3
4
5
6
7
8
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {   
             using (ZipFile zip = ZipFile.Read(zep))
                    {
                        zip.ExtractAll(raz);
                    }
             // сюда всё что связано с распаковкой
        }
если DoWork запущен происходит WorkerReportsProgress
C#
1
2
3
4
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }
Что-то нифига у меня не происходит никакой WorkerReportsProgress пока выполняется DoWork.
backgroundWorker1_ProgressChanged у меня выполняется только если я вызову backgroundWorker1.ReportProgress() в который нужно передать состояние прогресса, а где я его возьму? События от архиватора самому перехватывать? А зачем тогда нужен этот backgroundWorker1_ProgressChanged?

Добавлено через 42 минуты
А если я получаю события от zip, то нигде его не могу отобразить. При попытке обратиться к progressBar в событии вылазит ошибка, что я не могу обратиться к объекту созданному в другом потоке.

Добавлено через 18 часов 0 минут
Поможите люди добрые!
Дайте рабочий пример распаковки с прогресс баром, при использовании backgroundWorker.
0
Эксперт Java
4075 / 3809 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
11.04.2013, 21:53 19
Predatore, вы не подписались на событие SaveProgress.
0
28 / 23 / 8
Регистрация: 25.10.2009
Сообщений: 249
12.04.2013, 01:23 20
Цитата Сообщение от turbanoff Посмотреть сообщение
Predatore, вы не подписались на событие SaveProgress.
Наверное не SaveProgress, а ExtractProgress, т.к. я распаковываю архив. Собственно споткнувшись ещё об кучу ошибок, пришёл к более-менее чему-то странно шевелящемуся.
И так, я подписался на событие ExtractProgress и в событии этом пишу:
C#
1
2
3
4
if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
{
    backgroundOpenArchive.ReportProgress((int)(e.BytesTransferred * 100 / e.TotalBytesToTransfer));              
}
Из события я всё так же не могу на прямую обратиться к progressBar - ошибка разных потоков, но ReportProgress вызывается без проблем, видимо он для этого и нужен.
Далее, в backgroundWorker1_ProgressChanged я пишу следующее:
C#
1
progressBar.Value = e.ProgressPercentage;
Вроде бы должно работать, но не работает. Нет, никаких ошибок и даже что-то происходит... Прогресс бар, подёргивается периодически, как будто я даю ему какое-то значение, а потом тут же сбрасываю в ноль. Колеблется он в интервале, где-то не более 1-2%.
В ReportProgress я ноль не передаю, точно, проверял.
Но вот если в ProgressChanged написать так:
C#
1
2
if (e.ProgressPercentage > 0)
    progressBar.Value = e.ProgressPercentage;
То прогресс бар начинает колбасить по всей длине. Значит откуда-то ноль там таки берётся... Откуда? Сейчас ещё посмотрел, значение e.BytesTransferred колбасит во все стороны, оно то увеличивается, то уменьшается... Отсюда сделал не верное предположение, что это не всего передано байт, а передано между вызовами события. Почему не верное? Потому попробовал их суммировать и практически в момент превысил e.TotalBytesToTransfer
Кстати, в конце в ProgressChanged таки приходит значение 100 и прогрес бар весело заполняется.
Что я делаю не так? Как нормально отобразить прогресс?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.04.2013, 01:23

Распаковка ZIP архива / DotNetZip
Доброго времени суток уважаемые! Столкнулся с казалось бы, элементарной задачей: распаковать ZIP...

DotNetZip: архив скачивается, но не распаковывается
Здравствуйте! Учусь писать в MS Visual C#. Решил я сделать небольшой лаунчер с обновлением файлов...

Как установить библиотеку DotNetZip?
скачал библиотеку DotNetZip, но как установить пока что не в курсе, гугл не дает инфы.

Разархивирование Zip
https://www.cyberforum.ru/qt/thread450074.html#post3355459 QZip Выдает 120 ошибок в стиле...

Консольный progressbar или progressbar в TMemo
Здравствуйте. Хочу спросить ради интереса как создать вот такой ProgressBar но с указанием...

DotNetZip добавление папки с выбором подпапок
Всем Здравствуйте. Пробую архивировать с библиотекой DotNetZip. Есть папка с подпапками и файлами...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.