/******************************
* 说明:自动更新类
* 创建人:龚宇超
* 创建日期:2018-02-09
* 修改人:
* 修改日期:
* 修改备注:
* 版本:1.0.0.0
******************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace Lskj.AutoUpdate
{
///
/// 自动更新类
///
public class AutoUpdater : IAutoUpdater
{
private bool _isMes = false;
private bool _needRestart;
private bool _download;
private bool _mainLoad;
public Config _config;
private List _downloadFileListTemp;
private bool _rollbackCompleted = false;
public AutoUpdater()
{
_config = new Config().LoadConfig(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstModel.AUTOUPDATE_CONFIG));
_mainLoad = false;
}
public AutoUpdater(string updateURL, bool mainload = true, bool isMes = false,string UpdateNotes="")
{
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstModel.AUTOUPDATE_CONFIG);
_config = new Config().LoadConfig(path);
_config.ServerUrl = updateURL;
_config.SaveConfig(path);
_config.UpdateNotes = UpdateNotes;
_mainLoad = mainload;
_isMes = isMes;
}
///
/// 说明:移动文件
/// 创建人:龚宇超
/// 创建日期:2018-02-23
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The old path.
/// The new path.
private void MoveFolderToOld(string oldPath, string newPath)
{
Exception lastException = null;
for (int i = 0; i < 10; i++)
{
try
{
if (File.Exists(oldPath) && File.Exists(newPath))
{
System.IO.File.Copy(oldPath, newPath, true);
}
return;
}
catch (IOException ex)
{
lastException = ex;
Thread.Sleep(500);
}
catch (UnauthorizedAccessException ex)
{
lastException = ex;
Thread.Sleep(500);
}
}
throw new IOException("文件可能仍被其他进程占用,重试后仍无法回滚:" + newPath, lastException);
//if (!File.Exists(oldPath) || !File.Exists(newPath))
// return;
//for (int i = 0; i < 5; i++)
//{
// try
// {
// File.Copy(oldPath, newPath, true);
// return;
// }
// catch
// {
// if (i < 4)
// System.Threading.Thread.Sleep(1000);
// }
//}
}
///
/// 说明:开始下载
/// 创建人:龚宇超
/// 创建日期:2018-02-23
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The download list.
private void StartDownload(List downloadList)
{
_rollbackCompleted = false;
FrmProgress dp = new FrmProgress(downloadList, this);
DialogResult result = dp.ShowDialog();
if (result != DialogResult.OK)
{
if (dp.IsUserCanceled)
return;
RollBack();
throw new Exception("更新未能完成,已尝试回滚。请确认主程序和相关客户端已关闭后重试。");
}
_config.SaveConfig(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstModel.AUTOUPDATE_CONFIG));
IniUtil.Write("ApplicationUpdateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm"));
if (_needRestart)
{
Directory.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstModel.TEMP_FOLDER_NAME), true);
MessageBox.Show(ConstModel.UPDATE_RESTART, ConstModel.LS_TITLE_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);
CommonUnitity.RestartApplication();
}
}
///
/// 说明:Xml 转换为下载集合
/// 创建人:龚宇超
/// 创建日期:2018-02-23
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The XML.
/// Dictionary<System.String, RemoteFile>.
private Dictionary ParseRemoteXml(string xml)
{
XmlDocument document = new XmlDocument();
//document.Load(xml);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(xml);
request.Timeout = 10000;
request.ReadWriteTimeout = 10000;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
document.Load(stream);
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.Timeout)
{
throw new Exception("连接超时:网络不稳定或服务器未响应。");
}
throw new Exception("网络请求失败: " + ex.Message);
}
Dictionary list = new Dictionary();
foreach (XmlNode node in document.DocumentElement.ChildNodes)
{
string key = node.Attributes["path"].Value;
if (!list.ContainsKey(key))
list.Add(key, new RemoteFile(node));
}
return list;
}
///
/// 说明:更新
/// 创建人:龚宇超
/// 创建日期:2018-02-23
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
public void Update()
{
Dictionary listRemotFile = ParseRemoteXml(_config.ServerUrl);
List downloadList = new List();
foreach (LocalFile file in _config.UpdateFileList)
{
if (listRemotFile.ContainsKey(file.Path))
{
RemoteFile rf = listRemotFile[file.Path];
string v1 = rf.Verison;
string v2 = file.Version;
if (v1 != v2)
{
downloadList.Add(new DownloadFileInfo(rf.Url, rf.Path, rf.LastVer, rf.Size, rf.Verison));
file.Path = rf.Path;
file.LastVer = rf.LastVer;
file.Size = rf.Size;
file.Version = rf.Verison;
if (rf.NeedRestart)
_needRestart = true;
_download = true;
}
listRemotFile.Remove(file.Path);
}
}
foreach (RemoteFile file in listRemotFile.Values)
{
downloadList.Add(new DownloadFileInfo(file.Url, file.Path, file.LastVer, file.Size, file.Verison));
_download = true;
_config.UpdateFileList.Add(new LocalFile(file.Path, file.LastVer, file.Size, file.Verison));
if (file.NeedRestart)
_needRestart = true;
}
_downloadFileListTemp = downloadList;
if (_download)
{
ProcessManager op = new ProcessManager();
FrmMain dc = new FrmMain(downloadList, _config.UpdateNotes);
//FrmMain dc = new FrmMain(downloadList);
if ((downloadList.Count > 0) && (_mainLoad))
{
DialogResult dlg = dc.ShowDialog();
if (dlg != DialogResult.OK)
{
return;
}
}
if (_mainLoad)
{
op.StartUpdateProcess(_isMes);
}
else
{
StartDownload(downloadList);
}
}
}
///
/// 说明:回滚
/// 创建人:龚宇超
/// 创建日期:2018-02-23
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
public void RollBack()
{
RollBack(false);
}
public void RollBack(bool silent)
{
if (_rollbackCompleted || _downloadFileListTemp == null)
return;
_rollbackCompleted = true;
foreach (DownloadFileInfo file in _downloadFileListTemp)
{
string tempUrlPath = CommonUnitity.GetFolderUrl(file);
string oldPath = string.Empty;
try
{
if (!string.IsNullOrEmpty(tempUrlPath))
{
oldPath = Path.Combine(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1), file.FileName);
}
else
{
oldPath = Path.Combine(CommonUnitity.SystemBinUrl, file.FileName);
}
if (oldPath.EndsWith("_"))
oldPath = oldPath.Substring(0, oldPath.Length - 1);
MoveFolderToOld(oldPath + ".old", oldPath);
}
catch (Exception ex)
{
if (!silent)
MessageBox.Show(ex.Message);
}
}
}
}
}