------ #### ryControls V3.0.2109.1201 - *.[改进]ObjectListView控件的AspectToStringConverter函数新增行数据参数。 - *.[改进]ObjectListView控件的行高默认到25像素。 - *.[改进]ObjectListView控件默认行选择而不是列选择。 - *.[改进]ObjectListView控件新增大量中文注释。 - *.[改进]ObjectListView控件的ShowGroups属性默认值为false。
533 lines
20 KiB
C#
533 lines
20 KiB
C#
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();
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|