有人能告诉我是否可以(如果可以的话并给出一个例子),如何使用“ZipFile”(Ionic.zip,http://dotnetzip.codeplex.com/)显示进度条(和状态标签,如果可能)来显示ZIP文件被解压缩的进度吗?
我的WinForm很好地从我选择的路径提取ZIP文件到新路径,使用文本框、浏览按钮等等没有问题......然而唯一的问题是在这个过程中我不能使用表单上的任何东西,它就像它已经冻结了,但实际上只是因为它正在后台解压缩ZIP文件。
ZIP文件是一个大文件,我想通过添加和使用进度条来显示解压缩的进度和准确的预计时间,使其更加清晰易懂。
这肯定是可能的,我只是无法弄清楚如何在C# WinForms中实现,我已经在网上搜索了相当长时间,但仍未能找到适合我的示例。
下面是我所拥有的粗略示例:
更新(2014年04月11日):我现在已经移除了文本框,回归到简单的基础功能。以下代码使用一个后台工作线程,但是取消按钮对RAR文件没有效果...有什么建议吗?
我的WinForm很好地从我选择的路径提取ZIP文件到新路径,使用文本框、浏览按钮等等没有问题......然而唯一的问题是在这个过程中我不能使用表单上的任何东西,它就像它已经冻结了,但实际上只是因为它正在后台解压缩ZIP文件。
ZIP文件是一个大文件,我想通过添加和使用进度条来显示解压缩的进度和准确的预计时间,使其更加清晰易懂。
这肯定是可能的,我只是无法弄清楚如何在C# WinForms中实现,我已经在网上搜索了相当长时间,但仍未能找到适合我的示例。
下面是我所拥有的粗略示例:
private void button1_Click(object sender, EventArgs e)
{
var ROBOT0007 = textBox1.Text + @"\" + "ROBOT0007"; //ROBOT0007 folder
var ROBOT_INSTALL = textBox1.Text + @"\" + "911" + @"\" + "files"; //ROBOT0007/911/files
var ROBOT_INSTALL_SPECIAL = ROBOT_INSTALL + @"\" + "special.rar"; //ROBOT0007/911/files/special.rar
//If the path has text...
if (textBox1.TextLength > 0)
{
//if the subfolder doesn't exist then make it.
if (!Directory.Exists(ROBOT0007))
{
Directory.CreateDirectory(ROBOT0007);
}
//if the textbox directory exists
if (Directory.Exists(ROBOT0007))
{
using (ZipFile zip = ZipFile.Read(ROBOT_INSTALL_SPECIAL))
{
zip.ExtractAll(ROBOT0007, ExtractExistingFileAction.OverwriteSilently);
}
}
}
}
更新(2014年04月11日):我现在已经移除了文本框,回归到简单的基础功能。以下代码使用一个后台工作线程,但是取消按钮对RAR文件没有效果...有什么建议吗?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Text;
using System.Windows.Forms;
using Ionic.Zip;
using System.IO;
namespace BackgroundWorkerSample
{
// The BackgroundWorker will be used to perform a long running action
// on a background thread. This allows the UI to be free for painting
// as well as other actions the user may want to perform. The background
// thread will use the ReportProgress event to update the ProgressBar
// on the UI thread.
public partial class Form1 : Form
{
/// <summary>
/// The backgroundworker object on which the time consuming operation
/// shall be executed
/// </summary>
BackgroundWorker backgroundWorker1;
public Form1()
{
InitializeComponent();
backgroundWorker1 = new BackgroundWorker();
// Create a background worker thread that ReportsProgress &
// SupportsCancellation
// Hook up the appropriate events.
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler
(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler
(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
/// <summary>
/// On completed do the appropriate task
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// The background process is complete. We need to inspect
// our response to see if an error occurred, a cancel was
// requested or if we completed successfully.
if (e.Cancelled)
{
lblStatus.Text = "Task Cancelled.";
}
// Check to see if an error occurred in the background process.
else if (e.Error != null)
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
// Everything completed normally.
lblStatus.Text = "Task Completed...";
}
//Change the status of the buttons on the UI accordingly
btnStart.Enabled = true;
btnCancel.Enabled = false;
}
/// <summary>
/// Notification is performed here to the progress bar
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// This function fires on the UI thread so it's safe to edit
// the UI control directly, no funny business with Control.Invoke :)
// Update the progressBar with the integer supplied to us from the
// ReportProgress() function.
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}
/// <summary>
/// Time consuming operations go here </br>
/// i.e. Database operations,Reporting
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// The sender is the BackgroundWorker object we need it to
// report progress and check for cancellation.
//NOTE : Never play with the UI thread here...
for (int i = 0; i < 100; i++)
{
//Thread.Sleep(100);
string INSTALL_FOLDER= "C:" + @"\" + "Program Files (x86)" + @"\" + "Robot91111"+ @"\" + "basic" + @"\" + "string" + @"\" + "special.rar";
string BURGOS_FOLDER = "C:" + @"\" + "Program Files (x86)" + @"\" + "Robot91111" + @"\" + "Burgos_Folder";
if (!Directory.Exists(BURGOS_FOLDER))
{
Directory.CreateDirectory(BURGOS_FOLDER);
using (ZipFile zip = ZipFile.Read(INSTALL_FOLDER))
{
zip.ExtractAll(BURGOS_FOLDER, ExtractExistingFileAction.OverwriteSilently);
}
}
// Periodically report progress to the main thread so that it can
// update the UI. In most cases you'll just need to send an
// integer that will update a ProgressBar
backgroundWorker1.ReportProgress(i);
// Periodically check if a cancellation request is pending.
// If the user clicks cancel the line
// m_AsyncWorker.CancelAsync(); if ran above. This
// sets the CancellationPending to true.
// You must check this flag in here and react to it.
// We react to it by setting e.Cancel to true and leaving
if (backgroundWorker1.CancellationPending)
{
// Set the e.Cancel flag so that the WorkerCompleted event
// knows that the process was cancelled.
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
//Report 100% completion on operation completed
backgroundWorker1.ReportProgress(100);
}
private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{
//Change the status of the buttons on the UI accordingly
//The start button is disabled as soon as the background operation is started
//The Cancel button is enabled so that the user can stop the operation
//at any point of time during the execution
btnStart.Enabled = false;
btnCancel.Enabled = true;
// Kickoff the worker thread to begin it's DoWork function.
backgroundWorker1.RunWorkerAsync();
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy)
{
// Notify the worker thread that a cancel has been requested.
// The cancel will not actually happen until the thread in the
// DoWork checks the backgroundWorker1.CancellationPending flag.
backgroundWorker1.CancelAsync();
}
}
}
}