123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.ComponentModel;
- using System.Threading;
- using System.Collections.Specialized;
- using System.Collections;
- using System.IO;
- using ProjectBase.Data.Zip;
- using ProjectBase.Data.Logs;
- namespace ProjectBase.Data.Update
- {
- /// <summary>
- /// 文件复制进度报告事件参数
- /// </summary>
- public class FileCopyProgressChangedEventArgs : ProgressChangedEventArgs
- {
- public FileCopyProgressChangedEventArgs(int progressPercentage, object userState)
- : base(progressPercentage, userState)
- {
- }
- /// <summary>
- /// 当前复制的字节数
- /// </summary>
- public double BytesToCopy { get; set; }
- /// <summary>
- /// 当前复制操作中的字节总数
- /// </summary>
- public double TotalBytesToCopy { get; set; }
- /// <summary>
- /// 当前复制的源文件名
- /// </summary>
- public string SourceFileName { get; set; }
- /// <summary>
- /// 当前复制的目标文件名
- /// </summary>
- public string TargetFileName { get; set; }
- public Manifest Manifest { get; set; }
- }
- /// <summary>
- /// 文件复制完成事件参数
- /// </summary>
- public class FileCopyCompletedEventArgs : AsyncCompletedEventArgs
- {
- public FileCopyCompletedEventArgs(Exception error, bool cancelled, object userState)
- : base(error, cancelled, userState)
- {
- }
- public Manifest Manifest { get; set; }
- }
- /// <summary>
- /// 文件复制错误事件参数
- /// </summary>
- public class FileCopyErrorEventArgs : EventArgs
- {
- public Exception Error { get; set; }
- public Manifest Manifest { get; set; }
- }
- /// <summary>
- /// 文件复制组件类
- /// </summary>
- public class FileCopyClass : Component
- {
- #region 变量定义
- private object defaultTaskId = new object();
- private int writeFileLength = 1024 * 64;
- private delegate void WorkerEventHandler(Manifest manifest, string sourcePath, AsyncOperation asyncOp);
- private SendOrPostCallback onProgressReportDelegate;
- private SendOrPostCallback onCompletedDelegate;
- private HybridDictionary userStateToLifetime = new HybridDictionary();
- private System.ComponentModel.Container components = null;
- #endregion
- #region 事件
- /// <summary>
- /// 文件复制进度事件
- /// </summary>
- public event EventHandler<FileCopyProgressChangedEventArgs> FileCopyProgressChanged;
- /// <summary>
- /// 文件复制完成事件
- /// </summary>
- public event EventHandler<FileCopyCompletedEventArgs> FileCopyCompleted;
- /// <summary>
- /// 文件复制错误事件
- /// </summary>
- public event EventHandler<FileCopyErrorEventArgs> FileCopyError;
- #endregion
- #region 构造及析构
- public FileCopyClass(IContainer container)
- {
- container.Add(this);
- InitializeComponent();
- InitializeDelegates();
- }
- public FileCopyClass()
- {
- InitializeComponent();
- InitializeDelegates();
- }
- protected virtual void InitializeDelegates()
- {
- onProgressReportDelegate = new SendOrPostCallback(ReportProgress);
- onCompletedDelegate = new SendOrPostCallback(CopyCompleted);
- }
- private void InitializeComponent()
- {
- components = new System.ComponentModel.Container();
- }
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
- #endregion
- #region 实现
- public int WriteFileLength
- {
- set
- {
- writeFileLength = value;
- }
- }
- public void Copy(Manifest manifest, string sourcePath)
- {
- string[] sourceFiles = null;
- string[] targetFiles = null;
- GetFiles(manifest, sourcePath, out sourceFiles, out targetFiles);
- for (int i = 0; i < sourceFiles.Length; i++)
- {
- if (!Directory.Exists(Path.GetDirectoryName(targetFiles[i])))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(targetFiles[i]));
- }
- File.Copy(sourceFiles[i], targetFiles[i], true);
- }
- }
- public void CopyAsync(Manifest manifest, string sourcePath)
- {
- CopyAsync(manifest, sourcePath, defaultTaskId);
- }
- public void CopyAsync(Manifest manifest, string sourcePath, object taskId)
- {
- AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(taskId);
- lock (userStateToLifetime.SyncRoot)
- {
- if (userStateToLifetime.Contains(taskId))
- {
- throw new ArgumentException("参数taskId必须是唯一的", "taskId");
- }
- userStateToLifetime[taskId] = asyncOp;
- }
- WorkerEventHandler workerDelegate = new WorkerEventHandler(FileCopyWorker);
- workerDelegate.BeginInvoke(manifest, sourcePath, asyncOp, null, null);
- }
- private bool TaskCanceled(object taskId)
- {
- return (userStateToLifetime[taskId] == null);
- }
- public void CancelAsync()
- {
- CancelAsync(defaultTaskId);
- }
- public void CancelAsync(object taskId)
- {
- AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
- if (asyncOp != null)
- {
- lock (userStateToLifetime.SyncRoot)
- {
- userStateToLifetime.Remove(taskId);
- }
- }
- }
- private void FileCopyWorker(Manifest manifest, string sourcePath, AsyncOperation asyncOp)
- {
- Exception exception = null;
- FileCopyProgressChangedEventArgs e = null;
- Stream rStream = null;
- Stream wStream = null;
- double writeBytes = 0;
- string[] sourceFiles = null;
- string[] targetFiles = null;
- GetFiles(manifest, sourcePath, out sourceFiles, out targetFiles);
- if (!TaskCanceled(asyncOp.UserSuppliedState))
- {
- try
- {
- double totalBytes = GetFileLength(sourceFiles);
- byte[] buffer = new byte[writeFileLength];
- int len = 0;
- int offset = 0;
- for (int i = 0; i < sourceFiles.Length; i++)
- {
- try
- {
- if (!Directory.Exists(Path.GetDirectoryName(targetFiles[i])))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(targetFiles[i]));
- }
- rStream = new FileStream(sourceFiles[i], FileMode.Open, FileAccess.Read, FileShare.None);
- wStream = new FileStream(targetFiles[i], FileMode.Create, FileAccess.Write, FileShare.None);
- while ((len = rStream.Read(buffer, offset, writeFileLength)) > 0)
- {
- wStream.Write(buffer, offset, len);
- writeBytes += len;
- e = new FileCopyProgressChangedEventArgs((int)(writeBytes / totalBytes * 100), asyncOp.UserSuppliedState);
- e.SourceFileName = sourceFiles[i];
- e.TargetFileName = targetFiles[i];
- e.TotalBytesToCopy = totalBytes;
- e.BytesToCopy += writeBytes;
- e.Manifest = manifest;
- asyncOp.Post(this.onProgressReportDelegate, e);
- Thread.Sleep(1);
- }
- }
- finally
- {
- DisposeStream(wStream);
- DisposeStream(rStream);
- }
- }
- }
- catch (Exception ex)
- {
- exception = ex;
- OnFileCopyError(new FileCopyErrorEventArgs() { Error = ex, Manifest = manifest });
- }
- }
- this.CompletionMethod(manifest, exception, TaskCanceled(asyncOp.UserSuppliedState), asyncOp);
-
- //如果文件是压缩文件,则解压这些文件
- ZipFiles(e.Manifest);
- }
- private void GetFiles(Manifest manifest, string sourcePath,out string[] sourceFiles,out string[] targetFiles)
- {
- sourceFiles = new string[manifest.ManifestFiles.Files.Length];
- targetFiles = new string[manifest.ManifestFiles.Files.Length];
- string path = Path.GetFullPath(manifest.MyApplication.Location);
- for (int i = 0; i < manifest.ManifestFiles.Files.Length; i++)
- {
- sourceFiles[i] = Path.Combine(sourcePath, manifest.ManifestFiles.Files[i].Source);
- targetFiles[i] = Path.Combine(path, manifest.ManifestFiles.Files[i].Source);
- }
- }
- private void DisposeStream(Stream stream)
- {
- if (stream != null)
- {
- stream.Flush();
- stream.Close();
- stream.Dispose();
- }
- }
- private double GetFileLength(string[] sourceFiles)
- {
- double bytes = 0;
- foreach (var file in sourceFiles)
- {
- FileInfo fileInfo = new FileInfo(file);
- bytes += fileInfo.Length;
- }
- return bytes;
- }
- private void CopyCompleted(object operationState)
- {
- FileCopyCompletedEventArgs e = operationState as FileCopyCompletedEventArgs;
- OnFileCopyCompleted(e);
- }
- private void ReportProgress(object state)
- {
- FileCopyProgressChangedEventArgs e = state as FileCopyProgressChangedEventArgs;
- OnProgressChanged(e);
- }
- protected void OnFileCopyCompleted(FileCopyCompletedEventArgs e)
- {
- if (FileCopyCompleted != null)
- {
- FileCopyCompleted(this, e);
- }
- }
- /// <summary>
- /// 如果文件是压缩文件,则解压这些文件
- /// </summary>
- /// <param name="manifest"></param>
- private void ZipFiles(Manifest manifest)
- {
- if (manifest != null)
- {
- string path = Path.GetFullPath(manifest.MyApplication.Location);
- foreach (ManifestFile file in manifest.ManifestFiles.Files)
- {
- bool unzip = false;
- bool.TryParse(file.Unzip, out unzip);
- if (file.Source.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) && unzip)
- {
- string zipFile = Path.Combine(path, file.Source);
- try
- {
- ZipUtility.UnZipFiles(zipFile, path, null, true);
- }
- catch (Exception ex)
- {
- LogHelper.log.Error("解压文件出现错误" + ex);
- }
- }
- }
- }
- }
- //public static void WriteLine(string message)
- //{
- // string temp = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + message + "\r\n\r\n";
- // string fileName = DateTime.Now.ToString("yyyyMMdd") + ".log";
- // try
- // {
- // File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName), temp, Encoding.GetEncoding("GB2312"));
- // }
- // catch (Exception ex)
- // {
- // LogHelper.log.Error();
- // }
- //}
- protected void OnProgressChanged(FileCopyProgressChangedEventArgs e)
- {
- if (FileCopyProgressChanged != null)
- {
- FileCopyProgressChanged(this, e);
- }
- }
- protected void OnFileCopyError(FileCopyErrorEventArgs e)
- {
- if (FileCopyError != null)
- {
- FileCopyError(this, e);
- }
- }
- private void CompletionMethod(Manifest manifest, Exception exception, bool canceled, AsyncOperation asyncOp)
- {
- if (!canceled)
- {
- lock (userStateToLifetime.SyncRoot)
- {
- userStateToLifetime.Remove(asyncOp.UserSuppliedState);
- }
- }
- FileCopyCompletedEventArgs e = new FileCopyCompletedEventArgs(exception, canceled, asyncOp.UserSuppliedState);
- e.Manifest = manifest;
- asyncOp.PostOperationCompleted(onCompletedDelegate, e);
- }
- #endregion
- }
- }
|