RaUI/Source/ryUpdate/myUpdate/clsLiveUpdate.cs
鑫Intel 83d0e095d5 ### 2021-09-12更新
------
#### ryControls    V3.0.2109.1201
- *.[改进]ObjectListView控件的AspectToStringConverter函数新增行数据参数。
- *.[改进]ObjectListView控件的行高默认到25像素。
- *.[改进]ObjectListView控件默认行选择而不是列选择。
- *.[改进]ObjectListView控件新增大量中文注释。
- *.[改进]ObjectListView控件的ShowGroups属性默认值为false。
2021-09-12 14:54:38 +08:00

533 lines
20 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using ryCommon;
//在线升级类
namespace LiveUpdate
{
/// <summary>
///
/// </summary>
public class ClsLiveUpdate
{
/// <summary>
/// 升级地址
/// </summary>
public string UpdateUrl = ""; //升级地址
private double SoftVer = 0; //软件版本
private double ReVer = 0; //软件修正版本
private string SoftDate = "";//软件日期
private string SoftUpdateDes = "";//软件更新描述
private string SoftUpdateDesUrl = "";//软件更新描述Url
private double DataVer = 0;//数据库版本
private string DataDate = "";//数据库日期
private string DataUpdateDes = "";//数据库更新描述
private string FileUpdateUrl = "";//文件更新地址
private string FileVerUpdateUrl = "";//针对文件版本不同使用不同下载地址
private string DbUpdateUrl = "";//数据库更新地址
/// <summary>
///
/// </summary>
public string CurUserId = "";//当前用户id
/// <summary>
/// 隔多久后再次检查更新
/// </summary>
private int UpdateAfterTime =0;
/// <summary>
/// 本地保存的配置信息
/// </summary>
public string SettingPath = "";//设置地址
/// <summary>
/// 当前安装的软件版本
/// </summary>
public double MySoftVer = 0; //软件版本
/// <summary>
/// 当前安装的软件修正版本
/// </summary>
public double MySoftRVer = 0; //软件修正版本
/// <summary>
/// 当前安装的数据库版本
/// </summary>
public double MyDataVer = 0;//数据库版本
/// <summary>
///
/// </summary>
public string SaveFileName = "tmp.tmp";//下载的文件保存文件
/// <summary>
///
/// </summary>
public string DownUrl = "";//下载地址
/// <summary>
///
/// </summary>
public bool isExit = false;
private UpdateInfo m_UpdateType;
/// <summary>
/// 获取当前更新的类型
/// </summary>
public UpdateInfo UpdateType
{
get { return m_UpdateType; }
}
/// <summary>
/// 每隔n小时检测一次更新
/// </summary>
public int UpdateLoopHours =0;//每隔n小时检测一次
private delegate void dd1(bool message);
private Thread threadOne;
/// <summary>
/// 读取版本信息完成后激发
/// </summary>
[Description("读取版本信息完成后激发")]
public event EventHandler OnReadComplete;
/// <summary>
/// 没有版本更新时激发
/// </summary>
[Description("没有版本更新时激发")]
public event EventHandler OnNoUpdate;
/// <summary>
/// 发现新版本时激发
/// </summary>
[Description("发现新版本时激发")]
public event UpdateHandler OnUpdateComplete;
/// <summary>
/// 发生错误后激发
/// </summary>
[Description("发生错误后激发")]
public event ErrorHandler OnHappenError;
/// <summary>
/// 更新进度变化后激发
/// </summary>
[Description("更新进度变化后激发")]
public event LiveUpdate.LiveUpdateProgressChanged ProgressChanged;
private LiveUpdate.LiveUpdateEventArgs _LiveUpdateEventArgs = new LiveUpdate.LiveUpdateEventArgs();
/// <summary>
/// 开始检测新版本
/// </summary>
public void StartLiveUpdate() //开始升级
{
if (threadOne != null) { threadOne.Abort(); }
threadOne = new Thread(new ThreadStart(GetVerInfo));
threadOne.SetApartmentState(ApartmentState.STA);
threadOne.IsBackground = true;
threadOne.Start();
}
/// <summary>
///
/// </summary>
public Form ParentForm = null;
/// <summary>
/// 初始化升级函数
/// </summary>
/// <param name="ower">为null,则表示事件运行在多线程模式下,否则,事件是在窗体所在线程下</param>
public ClsLiveUpdate(Form ower)
{
ParentForm = ower;
MySoftVer = AssemblyVersion;
MySoftRVer = AssemblyReVersion;
SettingPath = Application.StartupPath + @"\cUpdate.dat";
MyDataVer = 0;
}
/// <summary>
///
/// </summary>
public double AssemblyVersion
{
get
{
System.Diagnostics.FileVersionInfo info = System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
string[] ver_item = info.ProductVersion.Split('.');
if (ver_item.Length == 4)
{
return Convert.ToDouble(ver_item[0]+"."+ver_item[1]);
}
else
{
return Convert.ToDouble(info.ProductMajorPart + "." + info.ProductMinorPart);
}
}
}
/// <summary>
///
/// </summary>
public double AssemblyReVersion
{
get
{
System.Diagnostics.FileVersionInfo info = System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
string[] ver_item = info.ProductVersion.Split('.');
if (ver_item.Length == 4)
{
return Convert.ToDouble(ver_item[2] + "." + ver_item[3]);
}
else
{
return Convert.ToDouble(info.ProductBuildPart.ToString() + "." + info.ProductPrivatePart);
}
}
}
private void OnNoUpdate_T()
{
if (ParentForm != null)
{
ParentForm.Invoke(new Action(() =>
{
OnNoUpdate?.Invoke(this, new EventArgs());
}));
}
else
{
OnNoUpdate?.Invoke(this, new EventArgs());
}
}
private void OnReadComplete_T()
{
if (ParentForm != null)
{
ParentForm.Invoke(new Action(() =>
{
OnReadComplete?.Invoke(this, new EventArgs());
}));
}
else
{
OnReadComplete?.Invoke(this, new EventArgs());
}
}
private void OnUpdateComplete_T(UpdateInfo e)
{
if (ParentForm != null)
{
ParentForm.Invoke(new Action(() =>
{
OnUpdateComplete?.Invoke(e);
}));
}
else
{
OnUpdateComplete?.Invoke(e);
}
}
private void OnHappenError_T(UpdateErrorInfo e)
{
if (ParentForm != null)
{
ParentForm.Invoke(new Action(() =>
{
OnHappenError?.Invoke(e);
}));
}
else
{
OnHappenError?.Invoke(e);
}
}
/// <summary>
/// 获取版本信息
/// </summary>
private void GetVerInfo() //获取版本信息
{
#region
ryCommon.Storage MyXml2 = new ryCommon.Storage();
int iResult = 0;
MyXml2.LoadFromFile(SettingPath);
MyXml2.SelectNode("id", "UpdateAfterTime");
UpdateAfterTime = MyXml2.GetAttrValue("Value", 0);
DateTime LastUpdateTime;
MyXml2.SelectNode("id", "LastUpdateTime");
LastUpdateTime =MyXml2.GetAttrValue("Value", Convert.ToDateTime("2011-01-01"));
if (UpdateLoopHours > 0)
{
if ((DateTime.Now - LastUpdateTime).TotalHours.ToInt() < UpdateLoopHours)
{
OnNoUpdate_T();
return;
}
}
if (UpdateAfterTime > 0)
{
if ((DateTime.Now.Date - LastUpdateTime.Date).Days < UpdateAfterTime)
{
OnNoUpdate_T();
return;
}
}
MyXml2.SelectNode2("id", "LastUpdateTime");
MyXml2.SetAttrValue("Value", DateTime.Now.ToString());
MyXml2.SaveToFile(SettingPath);
#endregion
ryCommon.Storage MyXml = new ryCommon.Storage();
UpdateErrorInfo UpdateError;
iResult=MyXml.LoadFromFile(UpdateUrl);
if (iResult == 0)
{
UpdateError.ErrorId = 2;
UpdateError.ErrorStr = "更新错误,读取远程文件失败";
OnHappenError_T(UpdateError);
OnNoUpdate_T();
MyXml.LoadFromXMLText("<root></root>");
return;
}
string SoftVersion = "未知";
//软件版本
MyXml.SelectNode2("id", "SoftVer");
RySoft.GetVerByVerStr(MyXml.GetAttrValue("Value", "0"), out SoftVer, out ReVer);
//SoftVer = ConvertDouble(MyXml.GetAttrValue("Value","0"),0);
SoftVersion=MyXml.GetAttrValue("Value","0");
//数据库版本
MyXml.SelectNode2("id", "DataVer");
DataVer = MyXml.GetAttrValue("Value", 0d);
//软件更新地址
MyXml.SelectNode2("id", "FileUpdateUrl");
FileUpdateUrl = MyXml.GetAttrValue("Value", "");
//软件版本更新地址
MyXml.SelectNode2("id", "FileVerUpdateUrl");
FileVerUpdateUrl = MyXml.GetAttrValue("Value", "");
//数据库更新地址
MyXml.SelectNode2("id", "DbUpdateUrl");
DbUpdateUrl = MyXml.GetAttrValue("Value", "");
//软件日期
MyXml.SelectNode2("id", "SoftDate");
SoftDate = MyXml.GetAttrValue("Value", "");
//数据库日期
MyXml.SelectNode2("id", "DataDate");
DataDate = MyXml.GetAttrValue("Value", "");
//软件更新描述
MyXml.SelectNode2("id", "SoftUpdateDes");
SoftUpdateDes = MyXml.GetAttrValue("Value", "");
//软件更新描述Url
MyXml.SelectNode2("id", "SoftUpdateDesUrl");
SoftUpdateDesUrl = MyXml.GetAttrValue("Value", "");
//数据库更新描述
MyXml.SelectNode2("id", "DataUpdateDes");
DataUpdateDes = MyXml.GetAttrValue("Value", "");
//设置
MyXml.SelectNode2("id", "SettingXML");
string SettingXML = MyXml.GetAttrValue("Value", "");
//在下载升级包前首先要下载的内容
MyXml.SelectNode2("id", "FirstDownList");
string FirstDownList = MyXml.GetAttrValue("Value", "");
//允许更新的用户列表
MyXml.SelectNode2("id", "UpdateUserList");
string m_UpdateUserList ="|"+ MyXml.GetAttrValue("Value", "").Replace(";","|")+"|";
if (MyXml.GetAttrValue("Value", "") == "")
{
m_UpdateUserList = "";
}
//激发事件
OnReadComplete_T();
//更新标志,1表示软件更新,2表示数据库更新
int UpdateMarket = 0;//更新标志
UpdateInfo myUpdate;
myUpdate.UpdateDate = "";
myUpdate.UpdateDes = "";
myUpdate.UpdateDes_Url = "";
myUpdate.UpdateVer ="未知";
myUpdate.UpdateType = "";
myUpdate.UpdateUrl = "";
myUpdate.FirstDownList = FirstDownList;
myUpdate.sxSettingXML = SettingXML;
if(RySoft.CompareVer(MySoftVer, MySoftRVer, SoftVer, ReVer)==1)
{
UpdateMarket = 1;
myUpdate.UpdateDate = SoftDate;
myUpdate.UpdateDes = SoftUpdateDes;
myUpdate.UpdateVer = SoftVersion;
myUpdate.UpdateType = "soft";
myUpdate.UpdateDes_Url = SoftUpdateDesUrl;
if (FileVerUpdateUrl.Length > 0)
{
var list = FileVerUpdateUrl.Replace("\r", "").Split('\n');
for (int i = 0; i < list.Length; i++)
{
var item = list[i].Split('|');
if (item.Length < 2) { continue; }
var ver = item[0];
var url = item[1];
RySoft.GetVerByVerStr(ver, out var _softver, out var _rever);
if (RySoft.CompareVer(_softver, _rever, MySoftVer, MySoftRVer) <= 0)
{
FileUpdateUrl = url; break;
}
}
}
myUpdate.UpdateUrl = FileUpdateUrl;
DownUrl = FileUpdateUrl;
}
else
{
if (MyDataVer < DataVer) //如果本地数据库版本小于远程服务器版本
{
UpdateMarket = 2;
myUpdate.UpdateDate = DataDate;
myUpdate.UpdateDes = DataUpdateDes;
myUpdate.UpdateVer = DataVer.ToString("0.000");
myUpdate.UpdateType = "data";
myUpdate.UpdateUrl = DbUpdateUrl;
DownUrl = DbUpdateUrl;
}
}
if (UpdateMarket > 0)
{
//如果没有指定更新用户,或者包含在指定更新用户里,则有更新
if (m_UpdateUserList.Length==0 || (m_UpdateUserList).IndexOf("|" + CurUserId + "|") >= 0)
{
if (m_UpdateUserList.Length > 0 && CurUserId.Length == 0)
{
OnNoUpdate_T();
}
else
{
m_UpdateType = myUpdate;
OnUpdateComplete_T(myUpdate);
}
}
else
{
OnNoUpdate_T();
}
}
else
{
OnNoUpdate_T();
}
}
Thread threadDown;
/// <summary>
/// 开始下载
/// </summary>
public void StartDownload()
{
isExit = false;
if (threadDown != null)
{
threadDown.Abort();
}
threadDown = new Thread(new ThreadStart(_Download))
{
IsBackground = true
};
threadDown.Start();
}
/// <summary>
/// 开始下载
/// </summary>
public void StartDownload(string fileurl, string filename)
{
isExit = false;
if (threadDown != null)
{
threadDown.Abort();
}
threadDown = new Thread(delegate () { _Download(fileurl, filename); });
threadDown.IsBackground = true;
threadDown.Start();
}
/// <summary>
/// 下载,不使用多线程
/// </summary>
public bool DownloadInUI(string fileurl, string filename)
{
isExit = false;
return _Download(fileurl, filename);
}
/// <summary>
/// 结束下载
/// </summary>
public void StopDownload()
{
if (threadDown != null)
{
threadDown.Abort();
}
}
private void _Download()
{
_Download(DownUrl, Application.StartupPath + "\\Update\\" + SaveFileName);
}
private bool _Download(string fileurl, string filename)
{
int retry = 0;
retryits:
try
{
System.Net.ServicePointManager.DefaultConnectionLimit = 512;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(fileurl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
long totalBytes = response.ContentLength;
Stream st = response.GetResponseStream();
Stream so = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
_DoEvent(fileurl, filename, totalBytes, 0, false, "开始下载....");
long totalDownloadedByte = 0;
byte[] by = new byte[4096];
int osize = st.Read(by, 0, (int)by.Length);
while (osize > 0)
{
if (isExit)
{ break; }
totalDownloadedByte = osize + totalDownloadedByte;
so.Write(by, 0, osize);
osize = st.Read(by, 0, (int)by.Length);
double p = totalDownloadedByte * 100.0 / totalBytes;
if (p >= 100.0) p = 100.0;
_DoEvent(fileurl, filename, totalBytes, p, false, String.Format("正在下载:{0}",RyFiles.GetFileSizeStr(totalDownloadedByte)));
}
so.Close();
st.Close();
_DoEvent(fileurl, filename, totalBytes, 100, true, "下载完成");
if (isExit) { return false; }
return true;
}
catch (Exception ex)
{
retry++;
if (retry < 5)
{
_DoEvent(fileurl, filename, 0, 0, false, String.Format("下载失败,第 {0} 次重试", retry));
// 休息 5 秒钟然后重试
Thread.Sleep(5000);
goto retryits;
}
else
{
_DoEvent(fileurl, filename, 0, 0, false, "下载失败,原因是:" + ex.Message);
return false;
}
}
finally
{
Thread.Sleep(100);
}
}
private void _DoEvent(string url, string filename, long filesize, double progress, bool iscompleted, string currentstatus)
{
if (ProgressChanged != null)
{
_LiveUpdateEventArgs.CurrentFileName = filename;
_LiveUpdateEventArgs.CurrentFileSize = filesize;
_LiveUpdateEventArgs.CurrentUrl = url;
_LiveUpdateEventArgs.CurrProgress = progress;
_LiveUpdateEventArgs.IsCompleted = iscompleted;
_LiveUpdateEventArgs.CurrentStatus = currentstatus;
this.ProgressChanged(this, _LiveUpdateEventArgs);
Application.DoEvents();
}
}
}
}