using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Media.Imaging; using Install.Core.Common; namespace Update.Core { public class InstallWizard : INotifyPropertyChanged { public string Msg { get; private set; } /// <summary> /// 进度 100% 满 /// </summary> public double Progress { get; private set; } /// <summary> /// 总安装列表 /// </summary> [PropertyChanged.DoNotNotify] public InstallPackCollection InstallPacks { get; private set; } /// <summary> /// //已经安装的软件列表 /// </summary> [PropertyChanged.DoNotNotify] public List<InstallInfo> HasInstalled { get; } = new List<InstallInfo>(); /// <summary> /// 图标列表 /// </summary> public Dictionary<string, BitmapSource> Icons { get; } = new Dictionary<string, BitmapSource>(); /// <summary> /// 有更加新的安装包 /// </summary> public bool HasNewestInstallZip { get; private set; } /// <summary> /// 从网络检测信息中 /// </summary> public bool IsCheckingNetwork { get; private set; } /// <summary> /// 最新的安装包版本 /// </summary> public string NewestInstallZipVersion { get; private set; } /// <summary> /// 当前的安装包版本 /// </summary> public string CurrentInstallZipVersion { get; private set; } public NewestInstallZipVersionInfo NewestInstallZipVersionInfo { get; private set; } #region 下载包 public double DownloadInfo_Progress => DownloadInfo_TotalSize > 0 ? 1.0 * DownloadInfo_CurrSize / DownloadInfo_TotalSize : 0; public long DownloadInfo_TotalSize { get; private set; } public long DownloadInfo_CurrSize { get; private set; } public string DownloadInfo_TotalSizeStr => fileSize2Str(DownloadInfo_TotalSize); public string DownloadInfo_CurrSizeStr => fileSize2Str(DownloadInfo_CurrSize); public string DownloadInfo_SpeedStr { get; private set; } public string DownloadInfo_ElapsedTimeStr { get; private set; } public string DownloadInfo_RemainingTimeStr { get; private set; } public string DownloadInfo_ErrMsg { get; private set; } #endregion public event PropertyChangedEventHandler PropertyChanged; public InstallWizard() { } void NotifyPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public bool Init() { if(!LoadInstallPacks()) return false; UpdateHasInstalled(); UpdateIcons(); DownloadNewestInstallZipInfo(); return true; } /// <summary> /// 下载最新的安装包信息 /// </summary> void DownloadNewestInstallZipInfo() { IsCheckingNetwork = true; //新建线程 Task.Factory.StartNew(() => { var bytes = HttpExt.HttpDownload(InstallPacks.NewestInstallZipVersionInfoPath); if (bytes == null) return; //bytes 转 string string json = System.Text.Encoding.UTF8.GetString(bytes); NewestInstallZipVersionInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<NewestInstallZipVersionInfo>(json); NewestInstallZipVersion = NewestInstallZipVersionInfo.InstallZipVersion; int ret = VerExt.VersionCompare(InstallPacks.InstallZipVersion, NewestInstallZipVersionInfo.InstallZipVersion); IsCheckingNetwork = false; HasNewestInstallZip = (ret < 0); }); } string fileSize2Str(long fileSizeByte) { double fileSize = fileSizeByte; int i = 0; while (fileSize > 1024) { i++; fileSize /= 1024; if (i >= 2) break; } switch (i) { case 0: return $"{fileSize:F0}B"; case 1: return $"{fileSize:F3}KB"; default://case 2: return $"{fileSize:F3}MB"; } } string fileSpeed2Str(long fileSpeedBytePerSec) { double fileSpeed = fileSpeedBytePerSec; int i = 0; while (fileSpeed > 1024) { i++; fileSpeed /= 1024; if (i >= 2) break; } switch (i) { case 0: return $"{ fileSpeed:F0}B/s"; case 1: return $"{ fileSpeed:F1}KB/s"; default://case 2: return $"{ fileSpeed:F1}MB/s"; } } string sec2Str(int sec) { if (sec > 60) return $"{(int)(sec / 60)}分 {sec % 60}秒"; else return $"{sec % 60}秒"; } public string NewestInstallZipPath { get; private set; } /// <summary> /// 下载最新的安装包 /// </summary> public async Task<bool> DownloadNewestInstallZip() { //新建线程 var ret = await Task.Factory.StartNew(() => { string path; if (string.IsNullOrEmpty(InstallPacks.DefaultNewestInstallZipPath)) { //下载到当前 exe 的上级目录 path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; path = Path.GetDirectoryName(path); path = Path.GetDirectoryName(path); } else { path = InstallPacks.DefaultNewestInstallZipPath; } path = Path.Combine(path, NewestInstallZipVersionInfo.InstallZipName); NewestInstallZipPath = path; try { HttpExt.BreakpointDownload( NewestInstallZipVersionInfo.InstallZipUrl, NewestInstallZipPath+".7z", false, (totalSize) => DownloadInfo_TotalSize = totalSize, (currSize) => DownloadInfo_CurrSize = currSize, (speed) => DownloadInfo_SpeedStr = fileSpeed2Str(speed), (sec) => DownloadInfo_ElapsedTimeStr = sec2Str(sec), (sec) => DownloadInfo_RemainingTimeStr = sec2Str(sec)); DownloadInfo_ErrMsg = null; return true; } catch (Exception e) { DownloadInfo_ErrMsg = e.Message; return false; } }); return ret; } /// <summary> /// 加载安装包 /// </summary> bool LoadInstallPacks() { string installpack_path = "install.json"; InstallPackCollection installPackCollection; try { Msg = $"加载 {installpack_path}"; string json = File.ReadAllText(installpack_path); installPackCollection = Newtonsoft.Json.JsonConvert.DeserializeObject<InstallPackCollection>(json); } catch { Msg = $"加载 {installpack_path} 失败"; return false; } InstallPacks = installPackCollection; NotifyPropertyChanged(nameof(InstallPacks)); CurrentInstallZipVersion = InstallPacks.InstallZipVersion; return true; } /// <summary> /// 更新已经安装的软件 /// </summary> void UpdateHasInstalled() { HasInstalled.Clear(); var installInfos = InstallInfoHelper.GetInstallInfos(); if (installInfos.Count() > 0) { HasInstalled.AddRange(installInfos); } //之前不是安装的,是直接复制到D盘运行的 installInfos = InstallInfoHelper.GetInstallInfosFromPath(InstallPacks); if (installInfos.Count() > 0) { //一样的不复制进去 foreach (var installInfo in installInfos) { if (HasInstalled.Exists(ii => ii.InstallPath == installInfo.InstallPath)) continue; HasInstalled.Add(installInfo); } } NotifyPropertyChanged(nameof(HasInstalled)); } /// <summary> /// 更新在 安装包中的 图标列表 /// </summary> void UpdateIcons() { Icons.Clear(); foreach (var installInfo in HasInstalled) { string exePath = $@"{installInfo.InstallPath }\{installInfo.Exe }"; var bitmapSource = IconExt.GetIcon(exePath); if (bitmapSource != null) { Icons.Add(installInfo.ProcessName, bitmapSource); } } } } }