C/S架构系统的自动更新功能设计与实现(三)

服务端配置管理

配置文件

<appSettings>
 <!--版本目录(相对或绝对路径)-->
 <add key="VersionDir" value="E:\Test\XXXX网络版软件版本库" />
 <!--主版本文件名-->
 <add key="MainVersionFile" value="XXXX.XXXX.exe"/>
</appSettings>

配置文件读取

/// <summary>
/// 根据键获取配置值,并将该值作为路径处理后返回
/// </summary>
/// <param name="sKey">路径</param>
/// <returns>绝对路径</returns>
public static string GetConfigAbsolutePath(string sKey)
{
	var sPath = GetConfigString(sKey);
	if (!string.IsNullOrEmpty(sPath))
	{
		if (sPath.StartsWith("~"))
		{
			sPath = System.Web.Hosting.HostingEnvironment.MapPath(sPath);  //转为绝对路径
		}
	}
	else
	{
		sPath = "";
	}
	return sPath;
}

/// <summary>
/// 获取配置中的字符串
/// </summary>
/// <param name="sKey">键名</param>
/// <returns>值</returns>
public static string GetConfigString(string sKey)
{
	return System.Configuration.ConfigurationManager.AppSettings[sKey]?.ToString().Trim();
}

服务接口开发

/// <summary>
/// 版本升级服务
/// </summary>
public class UpgradeController : ApiController
{
	/// <summary>
	/// 获取升级信息(完整版)
	/// </summary>
	/// <returns>完整升级信息</returns>
	/// <status>可用</status>
	[HttpGet]
	[ResponseType(typeof(ResponseInfo))]
	public IHttpActionResult Info()
	{
		try
		{
			return Json(new ResponseOk() { Data = UpgradeHelper.GetUpgradeInfo() } as ResponseInfo);
		}
		catch (Exception ex)
		{
			ExceptionHelper.LogActionException(ex);
			return Json(new ResponseError(ex) as ResponseInfo);
		}
	}


	/// <summary>
	/// 获取升级信息(仅摘要)
	/// </summary>
	/// <returns>升级信息摘要</returns>
	/// <status>可用</status>
	[HttpGet]
	[ResponseType(typeof(ResponseInfo))]
	public IHttpActionResult Abstract()
	{
		try
		{
			return Json(new ResponseOk() { Data = new UpgradeInfoAbstract(UpgradeHelper.GetUpgradeInfo()) } as ResponseInfo);
		}
		catch (Exception ex)
		{
			ExceptionHelper.LogActionException(ex);
			return Json(new ResponseError(ex) as ResponseInfo);
		}
	}

	/// <summary>
	/// 获取升级文件列表
	/// </summary>
	/// <returns>升级文件相对路径列表</returns>
	/// <status>可用</status>
	[HttpGet]
	[ResponseType(typeof(ResponseInfo))]
	public IHttpActionResult Files()
	{
		try
		{
			return Json(new ResponseOk() { Data = new UpgradeFilesInfo(UpgradeHelper.GetUpgradeInfo()) } as ResponseInfo);
		}
		catch (Exception ex)
		{
			ExceptionHelper.LogActionException(ex);
			return Json(new ResponseError(ex) as ResponseInfo);
		}
	}

	/// <summary>
	/// 下载升级文件
	/// </summary>
	/// <param name="param">文件相对路径,如:Scripts\\Rules\\B002G009.py</param>
	/// <returns>包含文件流的响应消息</returns>
	/// <status>可用</status>
	[HttpGet]
	[ResponseType(typeof(ResponseMessageResult))]
	public IHttpActionResult Stream([FromUri]string param)
	{
		var response = new HttpResponseMessage(HttpStatusCode.OK);
		try
		{
			if (string.IsNullOrEmpty(param))
			{
				throw new Exception("参数为空");
			}
			var sPath = Path.Combine(UpgradeHelper.LatestVersionFolder, param.ToString());
			if (!File.Exists(sPath))
			{
				throw new Exception($"未能找到文件{sPath}");
			}
			FileStream fileStream = new FileStream(sPath, FileMode.Open);
			response.Content = new StreamContent(fileStream);
			response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
			response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
			{
				FileName = param
			};
		}
		catch (Exception ex)
		{
			ExceptionHelper.LogActionException(ex);
			response.StatusCode = HttpStatusCode.NotFound;
			response.Content = null;
		}
		return ResponseMessage(response);
	}
}

辅助方法类

/// <summary>
/// 升级助手类
/// </summary>
public class UpgradeHelper
{
	private static string _versionFolder = "";
	/// <summary>
	/// 版本目录(存放所有版本的文件夹)
	/// </summary>
	public static string VersionFolder
	{
		get
		{
			_versionFolder = Path.Combine(GlobalHelper.GetConfigAbsolutePath("VersionDir"));
			if (!Directory.Exists(_versionFolder))
				Directory.CreateDirectory(_versionFolder);
			return _versionFolder;
		}
	}

	private static string _latestVersionFolder = "";
	/// <summary>
	/// 版本目录(存放最新版本的文件夹)
	/// </summary>
	public static string LatestVersionFolder
	{
		get
		{
			_latestVersionFolder = GetLatestVersionFolder(VersionFolder);
			if (!Directory.Exists(_latestVersionFolder))
				Directory.CreateDirectory(_latestVersionFolder);
			return _latestVersionFolder;
		}
	}

	/// <summary>
	/// 获取最新版本文件夹
	/// </summary>
	/// <param name="sVersionFolder"></param>
	/// <returns></returns>
	public static string GetLatestVersionFolder(string sVersionFolder)
	{
		var sLatestVersionFolder = "";
		try
		{
			if (string.IsNullOrEmpty(sVersionFolder))
			{
				throw new Exception("根目录为空");
			}
			if (!Directory.Exists(sVersionFolder))
			{
				throw new Exception($"目录不存在{sVersionFolder}");
			}
			var dirInfo = new DirectoryInfo(sVersionFolder);
			var lstDir = dirInfo.GetDirectories();
			if (null == lstDir || 0 >= lstDir.Count())
			{
				throw new Exception($"目录{sVersionFolder}不存在下级目录");
			}
			SortByLastWriteTimeDesc(ref lstDir);
			sLatestVersionFolder = lstDir.ElementAt(0).FullName;
		}
		catch (Exception ex)
		{
			Log.Loging.Error(ex.Message);
		}
		return sLatestVersionFolder;
	}

	/// <summary>
	/// 按文件夹最后更新时间排序(倒序)
	/// </summary>
	/// <param name="dirs">待排序文件夹数组</param>
	private static void SortByLastWriteTimeDesc(ref DirectoryInfo[] dirs)
	{
		Array.Sort(dirs, delegate (DirectoryInfo x, DirectoryInfo y) { return y.LastWriteTime.CompareTo(x.LastWriteTime); });
	}

	/// <summary>
	/// 获取目标目录下以及其子目录下的所有文件(采用相对路径)
	/// </summary>
	/// <param name="sDir">目录路径</param>
	/// <returns>文件相对路径集合</returns>
	public static List<string> GetOffspringFiles(string sDir)
	{
		var lstFile = new List<string>();
		try
		{
			var dirInfo = new DirectoryInfo(sDir);
			var lstFileInfo = dirInfo.EnumerateFiles("*", SearchOption.AllDirectories)?.ToList();
			if (null != lstFileInfo && 0 < lstFileInfo.Count)
			{
				lstFileInfo.ForEach(p =>
				{
					lstFile.Add(p.FullName.Substring(sDir.Length).TrimStart('\\'));
				});
			}
		}
		catch (Exception ex)
		{
			ExceptionHelper.LogActionException(ex);
			lstFile.Clear();
		}
		return lstFile;
	}

	/// <summary>
	/// 获取升级信息
	/// </summary>
	/// <param name="sVersionFolder">此版本的完整目录路径</param>
	/// <param name="sMainVersionFile">主程序文件名(如:Main.exe)</param>
	/// <returns>升级信息</returns>
	public static UpgradeInfo GetUpgradeInfo(string sVersionFolder, string sMainVersionFile)
	{
		var upgradeInfo = new UpgradeInfo();
		var lstFile = GetOffspringFiles(sVersionFolder);
		foreach (string sRelativePath in lstFile)
		{
			upgradeInfo.FileUnits.Add(new FileUnit(sVersionFolder, Path.Combine(sVersionFolder, sRelativePath.TrimStart('\\'))));
		}
		((List<FileUnit>)(upgradeInfo.FileUnits)).Sort();
		string sMainFullPath = null; //主版本程序路径
		if (!string.IsNullOrEmpty(sMainVersionFile))
		{
			var sRelativePath = lstFile.FirstOrDefault(p => p.Contains(sMainVersionFile))?.TrimStart('\\');
			if (!string.IsNullOrEmpty(sRelativePath))
			{
				sMainFullPath = Path.Combine(sVersionFolder, sRelativePath);
				if (!File.Exists(sMainFullPath))
				{
					sMainFullPath = null;
				}
			}
		}
		var sLatestMainVersion = "N/A";
		if (!string.IsNullOrEmpty(sMainFullPath))
		{
			var fileInfo = new FileInfo(sMainFullPath);
			sLatestMainVersion = $"{fileInfo.Name.Substring(0, fileInfo.Name.Length - fileInfo.Extension.Length)} {FileUnit.GetFileVersion(sMainFullPath)}";
			upgradeInfo.MainVersionInfo = FileUnit.GetFileVersionInfo(sMainFullPath);
		}
		return upgradeInfo;
	}

	/// <summary>
	/// 获取升级信息(根据默认配置自动获取)
	/// </summary>
	/// <returns>升级信息</returns>
	public static UpgradeInfo GetUpgradeInfo()
	{
		return GetUpgradeInfo(LatestVersionFolder, GlobalHelper.GetConfigString("MainVersionFile"));
	}
}

接口页面

WebAPI列表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值