using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Muchinfo.MTPClient.Update
{
///
/// UpdateForm.xaml 的交互逻辑
///
public partial class UpdateForm : Window
{
public UpdateForm(string updateUrl ,UpdateInfo updateInfo)
{
InitializeComponent();
applictionUpdateUrl = updateUrl;
updateInfos = updateInfo;
this.Loaded += MainWindow_Loaded;
this.bnt_Close.Click += bnt_Close_Click;
this.MouseDown += new MouseButtonEventHandler(Window_MouseDown);
//this.Closing += MainWindow_Closing;
Application.Current.Exit += Current_Exit;
}
// private Queue _downList = new Queue();
const string Update_GetConfigEx = "获取配置文件异常";
const string APP_Updating = "应用程序正在更新...";
const string Update_NoNewFileDowm = "没有提供最新的文件下载";
const string Update_GetServiceFileEx = "获取服务器文件信息出错";
const string Update_NowDownFile = "正在下载文件";
const string Update_FileAllFinish = "全部下载完成";
private const string update_bakDir = "Update_bak";
private const string update_Dir = "Update";
private UpdateInfo updateInfos;
private string applictionUpdateUrl;
private WebClient webClient = null;
///
/// 程序文件夹
///
private string localAppFolder = AppDomain.CurrentDomain.BaseDirectory;
///
/// 更新文件夹
///
private string localUpdateFolder = AppDomain.CurrentDomain.BaseDirectory + update_Dir;
///
/// 备份文件夹
///
private string localBackupFolder = AppDomain.CurrentDomain.BaseDirectory + update_bakDir;
///
/// 消息提示
///
private string msg = string.Empty;
///
/// 总下载数
///
private float totalCount = 0f;
///
/// 当前下载数
///
private float totalCount_Completed = 0f;
///
/// 下载状态
///
private bool isRunning = false;
private Queue _downList = new Queue();
///
/// 下载列表
///
public Queue DownList
{
get { return _downList; }
set { _downList = value; }
}
#region 私有方法
#region 下载线程
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
try
{
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "Client.Update.old.exe"))
{
File.Delete(AppDomain.CurrentDomain.BaseDirectory + "Client.Update.old.exe");
}
if (updateInfos == null)
return;
if (updateInfos != null && updateInfos.UpdateFiles != null && !updateInfos.UpdateFiles.Any())
{
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
SetMessageText(Update_NoNewFileDowm);
}));
}
}
catch (Exception ex)
{
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
SetMessageText(Update_GetServiceFileEx);
}));
}
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (updateInfos != null && updateInfos.UpdateFiles != null && !updateInfos.UpdateFiles.Any())
{
return;
}
DownLoad();
}
#endregion
#region WebClient下载
public void DownLoad()
{
webClient = new WebClient();
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
webClient.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
//删除并且重新创建Update文件夹
if (Directory.Exists(localUpdateFolder))
{
Directory.Delete(localUpdateFolder, true);
}
Directory.CreateDirectory(localUpdateFolder);
this.totalCount = updateInfos.UpdateFiles.Count;
foreach (var updateFile in updateInfos.UpdateFiles)
{
DownList.Enqueue(updateFile);
}
UpdateFile updateFileInfo = DownList.Dequeue();
totalCount_Completed++;
this.msg = Update_NowDownFile + updateFileInfo.FilePath;
SetMessageText(this.msg);
string downloadfile= updateFileInfo.FilePath;
if (updateInfos.IsCompress && !updateFileInfo.IsConfig)
{
downloadfile =downloadfile.Substring(0,downloadfile.LastIndexOf(updateFileInfo.Extension))+".gz"; ////下载压缩文件
downloadfile= downloadfile.Replace('\\','/');
}
string localFileName = string.Format("{0}/{1}", localUpdateFolder, downloadfile);
string remotefile = string.Format("{0}/{1}", applictionUpdateUrl, downloadfile);
FileInfo fileInfo = new FileInfo(localFileName);
if (!Directory.Exists(fileInfo.DirectoryName))
{
Directory.CreateDirectory(fileInfo.DirectoryName);
}
//下载更新至本地
webClient.DownloadFileAsync(new Uri(remotefile), localFileName, updateFileInfo);
isRunning = true;
}
//下载中途,进度条控制,百分比显示
void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
float totalBytesToReceive = e.TotalBytesToReceive;
float bytesReceived = e.BytesReceived;
int progressPercentage = e.ProgressPercentage;
msg = (e.UserState as UpdateFile).FilePath;
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
pbCurrent.Value = progressPercentage;
tbCurrentControl.Text = (bytesReceived / totalBytesToReceive).ToString("0%");
}));
}
//下载完成
void webClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
SetMessageText((e.UserState as UpdateFile).FilePath + e.Error.Message);
isRunning = false;
return;
}
try
{
if (!isRunning)
{
return;
}
//进度条控制,百分比显示
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
pbTotal.Value = (100 / totalCount) * totalCount_Completed;
tbControl.Text = (totalCount_Completed / totalCount).ToString("0%");
}));
if (DownList.Count > 0)
{
UpdateFile updateFileInfo = DownList.Dequeue();
totalCount_Completed++;
this.msg = Update_NowDownFile + updateFileInfo.FilePath;
SetMessageText(this.msg);
string downloadfile = updateFileInfo.FilePath;
if (updateInfos.IsCompress && !updateFileInfo.IsConfig)
{
downloadfile = downloadfile.Substring(0, downloadfile.LastIndexOf(updateFileInfo.Extension)) + ".gz"; ////下载压缩文件
downloadfile = downloadfile.Replace('\\', '/');
}
string localFileName = string.Format("{0}/{1}", localUpdateFolder, downloadfile);
string remotefile = string.Format("{0}/{1}", applictionUpdateUrl, downloadfile);
FileInfo fileInfo = new FileInfo(localFileName);
if (!Directory.Exists(fileInfo.DirectoryName))
{
Directory.CreateDirectory(fileInfo.DirectoryName);
}
webClient.DownloadFileAsync(new Uri(remotefile), localFileName, updateFileInfo);
}
else
{
//全部下载完成
SetMessageText(APP_Updating);
BackUpdateFile();
ReplaceFiles();
CreateUpdateConfig();
SetMessageText(Update_FileAllFinish);
isRunning = false;
App.Current.Shutdown();
}
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 备份旧版本至bak
///
private void BackUpdateFile()
{
try
{
if (Directory.Exists(localBackupFolder))
{
Directory.Delete(localBackupFolder, true);
}
Directory.CreateDirectory(localBackupFolder);
foreach (var item in updateInfos.UpdateFiles)
{
string tempItem = item.FilePath.Replace('/', '\\');
if (File.Exists(localAppFolder + tempItem))
{
var directoryIndex = tempItem.LastIndexOf("\\", System.StringComparison.Ordinal);
if (directoryIndex > 0)
{
var directory = item.FilePath.Substring(0, directoryIndex);
Directory.CreateDirectory(localBackupFolder + "\\" + directory);
}
File.Copy(localAppFolder + tempItem, localBackupFolder + "\\" + tempItem, true);
}
}
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 下载更新的文件从Update覆盖到使用目录
///
private void ReplaceFiles()
{
try
{
foreach (var item in updateInfos.UpdateFiles)
{
//如果更新的是Muchinfo.MTPClient.Update,则先把源文件重命名,然后复制过去。最后删除重命名过的源文件
var isfileExists = File.Exists(localUpdateFolder + "\\" + item.FilePath) ||
File.Exists(localUpdateFolder + "\\" +
item.FilePath.Replace(item.Extension, ".gz"));
if (isfileExists)
{
if (item.FilePath == "Client.Update.exe")
{
File.Move(localAppFolder + item.FilePath, localAppFolder + "Client.Update.old.exe");
}
var directoryIndex = item.FilePath.LastIndexOf("\\", System.StringComparison.Ordinal);
if (directoryIndex > 0)
{
var directory = item.FilePath.Substring(0, directoryIndex);
var direPath = localAppFolder + "\\" + directory;
if (!Directory.Exists(direPath))
{
Directory.CreateDirectory(direPath);
}
}
if (updateInfos.IsCompress && !item.IsConfig) //解压文件
{
var compressFile = localUpdateFolder + "\\" + item.FilePath.Replace(item.Extension,".gz") ;
DeCompress(compressFile, localAppFolder + item.FilePath);
}
else
{
File.Copy(localUpdateFolder + "\\" + item.FilePath, localAppFolder + item.FilePath, true);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 对目标压缩文件解压缩,将内容解压缩到指定文件夹
///
/// 压缩文件
/// 解压缩目录
public static void DeCompress(string sourceName, string targetPath)
{
using (Stream source = File.OpenRead(sourceName))
{
using (FileStream destination = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
{
using (GZipStream input = new GZipStream(source, CompressionMode.Decompress, true))
{
byte[] bytes = new byte[4096];
int n;
while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
{
destination.Write(bytes, 0, n);
}
}
destination.Flush();
destination.Close();
}
}
}
///
/// 生成本地配置目录
///
private void CreateUpdateConfig()
{
var updateHelper = new UpdateHelper();
var updateInfo = updateHelper.CreateUpdateInfoFile(AppDomain.CurrentDomain.BaseDirectory, new string[] { update_bakDir, update_Dir });
var savePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
updateInfo.GetType().Name + ".xml");
updateHelper.SaveUpdateXml(updateInfo, savePath);
}
#endregion
void Current_Exit(object sender, ExitEventArgs e)
{
if (webClient != null)
{
webClient.Dispose();
}
if (updateInfos == null)
{
return;
}
//下载中途、完成后关闭Appliction程序
UpdateManage.RegisterChart(); ////图表更新
if (updateInfos.ReStart)
{
string appName = updateInfos.StartAppName;
if (!string.IsNullOrEmpty(appName))
{
string path = localAppFolder + appName;
if (File.Exists(path))
{
System.Diagnostics.Process.Start(path);
}
}
}
}
void bnt_Close_Click(object sender, RoutedEventArgs e)
{
App.Current.Shutdown();
}
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
DragMove();
}
private void SetMessageText(string text)
{
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
this.tbMessage.Text = text;
}));
}
#endregion
}
}