using ProjectBase.Data.Logs;
using ProjectBase.Data.Zip;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
namespace ProjectBase.Data.Update
{
///
/// 程序更新事件参数
///
public class ManifestEventArgs : EventArgs
{
public Manifest Manifest { get; set; }
}
///
/// 激活安装开始事件参数
///
public class ActivationStartedEventArgs : EventArgs
{
public Manifest Manifest { get; set; }
public bool Cancel { get; set; }
}
///
/// 安装完成事件参数
///
public class ActivationCompletedEventArgs : AsyncCompletedEventArgs
{
public ActivationCompletedEventArgs(Exception error, bool cancelled, object userState)
: base(error, cancelled, userState)
{
}
public Manifest Manifest { get; set; }
}
///
/// 程序自动更新操作类,封装了文件下载、文件复制、文件解压等操作
///
public class UpdateClass
{
#region 变量属性
private DownloadClass downloader = new DownloadClass();
private FileCopyClass fileCopyer = new FileCopyClass();
private UpdaterConfigurationView updateCfgView = new UpdaterConfigurationView();
private string backupFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../backup");
///
/// 封装的文件下载操作类
///
public DownloadClass Downloader
{
get
{
return downloader;
}
}
///
/// 封装的文件复制操作类
///
public FileCopyClass FileCopyer
{
get
{
return fileCopyer;
}
}
#endregion
#region 事件
///
/// 下载进度
///
public event EventHandler DownloadProgressChanged;
///
/// 下载完成事件
///
public event EventHandler DownloadCompleted;
///
/// 下载错误触发的事件
///
public event EventHandler DownloadError;
public event EventHandler ActivationInitializing;
public event EventHandler ActivationCompleted;
public event EventHandler ActivationStarted;
public event EventHandler ActivationProgressChanged;
public event EventHandler ActivationError;
#endregion
#region 下载更新实现
public UpdateClass()
{
downloader.DownloadCompleted += new EventHandler(downloader_DownloadCompleted);
downloader.DownloadError += new EventHandler(downloader_DownloadError);
downloader.DownloadProgressChanged += new EventHandler(downloader_DownloadProgressChanged);
fileCopyer.FileCopyError += new EventHandler(fileCopyer_FileCopyError);
fileCopyer.FileCopyCompleted += new EventHandler(fileCopyer_FileCopyCompleted);
fileCopyer.FileCopyProgressChanged += new EventHandler(fileCopyer_FileCopyProgressChanged);
}
///
/// 是否有最新的版本
///
public bool HasNewVersion
{
get
{
var m = CheckForUpdates();
return m.Length > 0;
}
}
///
/// 检查更新,返回更新清单列表
///
///
public Manifest[] CheckForUpdates()
{
updateCfgView.Refresh();
Uri uri = new Uri(updateCfgView.ManifestUri);
string doc = DownLoadFile(uri, updateCfgView.ManifestName, updateCfgView.ManifestPasswd);
XmlSerializer xser = new XmlSerializer(typeof(Manifest));
var manifest = xser.Deserialize(new XmlTextReader(doc, XmlNodeType.Document, null)) as Manifest;
if (manifest == null ||
manifest.Version == updateCfgView.Version ||
manifest.MyApplication.ApplicationId != updateCfgView.ApplicationId)
{
return new Manifest[0];
}
return new Manifest[] { manifest };
}
///
/// 用于远程下载文件清单
///
/// 文件清单网络路径
///
private string DownLoadFile(Uri uri, string username, string password)
{
WebRequest request = WebRequest.Create(uri);
request.Credentials = new NetworkCredential(username, password);
string response = String.Empty;
using (WebResponse res = request.GetResponse())
{
using (StreamReader reader = new StreamReader(res.GetResponseStream(), true))
{
response = reader.ReadToEnd();
}
}
return response;
}
///
/// 同步下载文件清单中的文件
///
/// 下载文件清单
public void Download(Manifest[] manifests)
{
foreach (var m in manifests)
{
downloader.Download(m);
}
}
///
/// 异步下载文件清单中的文件
///
/// 下载文件清单
public void DownloadAsync(Manifest[] manifests)
{
foreach (var m in manifests)
{
downloader.DownloadAsync(m);
}
}
///
/// 下载完毕后执行的启动操作
///
///
public void Activate(Manifest[] manifests)
{
foreach (var m in manifests)
{
OnActivationInitializing(new ManifestEventArgs() { Manifest = m });
Backup(m, downloader.TempPath);
ActivationStartedEventArgs e = new ActivationStartedEventArgs() { Manifest = m };
OnActivationStarted(e);
if (e.Cancel)
{
Clear();
break;
}
else
{
fileCopyer.CopyAsync(m, downloader.TempPath);
}
}
}
///
/// 备份操作
///
/// 文件清单
private void Backup(Manifest manifest, string sourcePath)
{
try
{
//string sourcePath = Path.GetFullPath(manifest.MyApplication.Location);
string s_filename = string.Empty;
string t_filename = string.Empty;
if (!Directory.Exists(backupFilePath))
{
Directory.CreateDirectory(backupFilePath);
}
foreach (var file in manifest.ManifestFiles.Files)
{
t_filename = Path.Combine(backupFilePath, file.Source);
s_filename = Path.Combine(sourcePath, file.Source);
if (File.Exists(s_filename))
{
File.Copy(s_filename, t_filename, true);
}
}
}
catch (Exception ex)
{
LogHelper.log.Error("备份文件出现错误" + ex);
}
}
///
/// 回滚文件下载内容
///
///
public void Rollback(Manifest manifest)
{
try
{
string filename = string.Empty;
foreach (var file in manifest.ManifestFiles.Files)
{
filename = Path.Combine(backupFilePath, file.Source);
File.Copy(filename, Path.Combine(Path.GetFullPath(manifest.MyApplication.Location), file.Source));
}
//Directory.Delete(backupFilePath, true);
}
catch (Exception ex)
{
LogHelper.log.Error("回滚文件出现错误" + ex);
}
}
///
/// 清除临时文件
///
private void Clear()
{
try
{
//Directory.Delete(backupFilePath, true);
Directory.Delete(downloader.TempPath, true);
}
catch (Exception ex)
{
LogHelper.log.Error("清理临时文件出现错误" + ex);
}
}
#endregion
#region 事件处理
private void fileCopyer_FileCopyError(object sender, FileCopyErrorEventArgs e)
{
OnActivationError(e);
}
private void fileCopyer_FileCopyProgressChanged(object sender, FileCopyProgressChangedEventArgs e)
{
if (ActivationProgressChanged != null)
{
ActivationProgressChanged(sender, e);
}
}
private void fileCopyer_FileCopyCompleted(object sender, FileCopyCompletedEventArgs e)
{
Clear();
try
{
//BackupSourceFiles(e.Manifest, updateCfgView.Version);
updateCfgView.Version = e.Manifest.Version;
}
catch (Exception ex)
{
LogHelper.log.Info("备份原始程序出错误, 错误为." + ex);
}
if (ActivationCompleted != null)
{
ActivationCompletedEventArgs evt = new ActivationCompletedEventArgs(e.Error, e.Cancelled, e.UserState);
evt.Manifest = e.Manifest;
OnActivationCompleted(evt);
}
}
///
/// 打包备份原始版本程序
///
///
private void BackupSourceFiles(Manifest manifest, string sourceVersion)
{
string folderFullName = new DirectoryInfo("../").FullName;//当前应用程序路径的上级目录 "../" + rootPath;
DirectoryInfo TheFolder = new DirectoryInfo(folderFullName);
foreach (DirectoryInfo NextFolder in TheFolder.GetDirectories())
{
if (NextFolder.Name == manifest.MyApplication.Expand)
{
string sourceFiles = folderFullName + NextFolder.Name;
string targetFiles = backupFilePath + "/" + NextFolder.Name + "_" + sourceVersion + ".zip";
ZipUtility.ZipFiles(sourceFiles, targetFiles, null);
}
}
}
private void downloader_DownloadProgressChanged(object sender, DownloadProgressEventArgs e)
{
if (DownloadProgressChanged != null)
{
DownloadProgressChanged(sender, e);
}
}
private void downloader_DownloadError(object sender, DownloadErrorEventArgs e)
{
if (DownloadError != null)
{
DownloadError(sender, e);
}
}
private void downloader_DownloadCompleted(object sender, DownloadCompleteEventArgs e)
{
if (DownloadCompleted != null)
{
DownloadCompleted(sender, e);
}
}
private void OnActivationInitializing(ManifestEventArgs e)
{
if (ActivationInitializing != null)
{
ActivationInitializing(this, e);
}
}
private void OnActivationStarted(ActivationStartedEventArgs e)
{
if (ActivationStarted != null)
{
ActivationStarted(this, e);
}
}
private void OnActivationCompleted(ActivationCompletedEventArgs e)
{
if (ActivationCompleted != null)
{
ActivationCompleted(this, e);
}
}
private void OnActivationError(FileCopyErrorEventArgs e)
{
if (ActivationError != null)
{
ActivationError(this, e);
}
}
private void OnActivationProgressChanged(FileCopyProgressChangedEventArgs e)
{
if (ActivationProgressChanged != null)
{
ActivationProgressChanged(this, e);
}
}
#endregion
}
}