自定义启动画面
需求
临近新中国成立70周年,项目团队计划发布一个以“70周年”为主题的版本。其中,能体现这一主题的,是系统的自动升级启动界面。该界面需要加载一张固定大小的图片。通过图片的修改和重新编译打包自动升级文件,来修改启动风格。
扩展一下这个需求,可以变成像很多常见的手机App或C/S客户端软件那样,动态加载启动画面。
这样的需求,该如何实现呢?其实不难。
原理
- 做一个接口,提供下载最新启动画面图片的功能,部署到服务器上。
- 客户端在加载时,首先从服务器上下载最新图片,下载不到时,使用本地或默认图片。
- 正常执行后续的各种操作(更新、启动等)。
实现
服务器端图片加载的服务接口
/// <summary>
/// 获取启动界面图片
/// </summary>
/// <returns>图片文件流</returns>
/// <status>可用</status>
[HttpGet]
[ResponseType(typeof(ResponseInfo))]
public IHttpActionResult Startup()
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
try
{
var sFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Startup");
if(!Directory.Exists(sFolder))
{
throw new Exception($"未能找到文件夹{sFolder}");
}
var lstFilePath = new List<string>();
lstFilePath.AddRange(Directory.GetFiles(sFolder, "*.png", SearchOption.TopDirectoryOnly));
lstFilePath.AddRange(Directory.GetFiles(sFolder, "*.jpg", SearchOption.TopDirectoryOnly));
var lstFileInfo = new List<FileInfo>();
lstFilePath.ForEach(p => lstFileInfo.Add(new FileInfo(p)));
var fileInfoArray = lstFileInfo.ToArray();
UpgradeHelper.SortByCreationTimeDesc(ref fileInfoArray);
var sPath = fileInfoArray[0].FullName;
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 = fileInfoArray[0].Name
};
}
catch (Exception ex)
{
ExceptionHelper.LogActionException(ex);
response.StatusCode = HttpStatusCode.NotFound;
response.Content = null;
}
return ResponseMessage(response);
}
在接口网站的根目录下添加一个Startup文件夹,放入启动图片(可放置多张,按文件的创建时间,每次取最新的。支持jpg或png格式)。
取最新图片的方法为:
/// <summary>
/// 按文件的创建时间排序(倒序)
/// </summary>
/// <param name="dirs">待排序文件数组</param>
public static void SortByCreationTimeDesc(ref FileInfo[] dirs)
{
Array.Sort(dirs, delegate (FileInfo x, FileInfo y) { return y.CreationTime.CompareTo(x.CreationTime); });
}
客户端加载最新启动图片的方法
/// <summary>
/// 设置启动图片
/// </summary>
private void SetStartupImage()
{
try
{
//设置启动图片
var sImageFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "upgrade");
Uri uri = null;
try
{
var sServerIP = m_sValueServerIP;
if (0 == string.Compare(sServerIP, "127.0.0.1", StringComparison.OrdinalIgnoreCase))
{
sServerIP = "localhost";
}
var nServerPort = m_nValueServerPort;
var sUrl = $"http://{sServerIP}:{nServerPort}/api/Upgrade/Startup";
var request = (HttpWebRequest)WebRequest.Create(sUrl);
request.Method = "GET";
var response = (HttpWebResponse)request.GetResponse();
if (HttpStatusCode.OK == response.StatusCode)
{
if (File.Exists(sImageFilePath))
File.Delete(sImageFilePath);
using (var fileStream = File.Create(sImageFilePath))
{
using (var stream = response.GetResponseStream())
{
stream.CopyTo(fileStream);
uri = new Uri(sImageFilePath);
}
}
}
if (response != null)
{
response.Close();
}
if (request != null)
{
request.Abort();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
if (uri == null && File.Exists(sImageFilePath))
{
uri = new Uri(sImageFilePath, UriKind.Absolute);
}
if (uri != null)
{
startImage.Source = new BitmapImage(uri);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}