private void OnMainAppStarted(LocalRunInfo localRunInfo, string msg) { this.Invoke((Action)(() => { if (string.IsNullOrEmpty(localRunInfo.ClientId)) { localRunInfo.ClientId = InputClientId(); } UpdateHelper.SaveLocalRunInfo(localRunInfo); _mainAppPath = localRunInfo.AppRunCmd.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; var urlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); this._config = UpdateHelper.GetSystemConfig(urlInfo.Host, urlInfo.SystemId); //var urlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); //this._config = UpdateHelper.GetSystemConfig(urlInfo.Host, urlInfo.SystemId); if (UpdateHelper.IsThisAppRunning() || !this._config.DetectEnabled) {// 保证更新程序只有一个在后台运行 Exit(localRunInfo); } else { StartUpdateDetect(localRunInfo, this._config); StartMainAppStateDetect(_mainAppPath, localRunInfo, this._config); } var appName = Path.GetFileName(_mainAppPath); notifyIcon.Text = this.Text = "更新检测-" + appName; LogHelper.LogInfoToServer($"程序启动成功({msg})", localRunInfo); })); }
public static void LogInfoToServer(string info, LocalRunInfo localRunInfo) { var updateUrlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); string url = $"{updateUrlInfo.Host}/api/LogInfo/{updateUrlInfo.SystemId}?clientId={Util.GetClientId(localRunInfo.ClientId)}&info={info}"; Util.SendHttpRequest(url); }
public MainAppStateDetector(string mainAppPath, LocalRunInfo localRunInfo, Config config) : base(config.PingInterval * 1000, true) { this.localRunInfo = localRunInfo; this.mainAppPath = mainAppPath; this.updateUrlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); this.clientId = Util.GetClientId(localRunInfo.ClientId); this.config = config; }
public static void LogErrorToServer(string msg, Exception ex, LocalRunInfo localRunInfo) { var updateUrlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); var error = $"{msg}:{ex.Message}{Environment.NewLine}{ex.StackTrace}"; string url = $"{updateUrlInfo.Host}/api/LogError/{updateUrlInfo.SystemId}?clientId={Util.GetClientId(localRunInfo.ClientId)}&error={error}"; Util.SendHttpRequest(url); }
/// <summary> /// 启动更新检测 /// </summary> /// <param name="localRunInfo"></param> /// <param name="config"></param> private void StartUpdateDetect(LocalRunInfo localRunInfo, Config config) { if (_updateDetector != null) { _updateDetector.Stop(); _updateDetector.OnStart -= OnUpdateDetectorStart; _updateDetector.OnStop -= OnUpdateDetectorStop; _updateDetector.OnNotifyUpdate -= OnUpdateNotification; } UpdateUrlInfo info = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl); _updateDetector = new UpdateDetector(config.DetectInterval * 1000, info); _updateDetector.OnStart += OnUpdateDetectorStart; _updateDetector.OnStop += OnUpdateDetectorStop; _updateDetector.OnNotifyUpdate += OnUpdateNotification; _updateDetector.Start(); }
private static void UpdateInternal(string msg) { LocalRunInfo localRunInfo = null; UpdateUrlInfo updateUrlInfo = null; try { OnStatus?.Invoke("正在读取本地配置..."); localRunInfo = GetLocalRunInfo(); OnStatus?.Invoke("正在验证更新地址..."); if (string.IsNullOrEmpty(localRunInfo.UpdateUrl)) { OnNotSpecifyUpdateUrl?.Invoke(localRunInfo); return; } if ((updateUrlInfo = UpdateUrlInfo.Parse(localRunInfo.UpdateUrl)) == null) { OnInvalidUpdateUrl?.Invoke(localRunInfo); return; } OnStatus?.Invoke("正在读取服务器..."); var host = updateUrlInfo.Host; var systemId = updateUrlInfo.SystemId; var remoteRunInfo = GetRemoteRunInfo(GetRemoteInfoUrl(host, systemId)); OnStatus?.Invoke("正在检测差异..."); var initStart = (localRunInfo.RunFiles.Count == 0); var fileDiffResults = CalcDiff(localRunInfo, remoteRunInfo).ToList(); var filesToUpdate = fileDiffResults.Where(f => f.Status == UpdateRunFileStatus.Update || f.Status == UpdateRunFileStatus.Delete).ToList(); var progress = 0; var total = filesToUpdate.Count; if (total > 0) { OnStatus?.Invoke("正在检测运行程序..."); if (IsThisAppRunning() || (!string.IsNullOrEmpty(localRunInfo.AppRunCmd) && IsMainAppRunning(localRunInfo))) { OnMainAppAlreadyRunning?.Invoke(localRunInfo); return; } } OnStatus?.Invoke("开始更新程序..."); OnBeginUpdate?.Invoke(localRunInfo); var runDir = Path.GetDirectoryName(Application.ExecutablePath); var thisExeName = Path.GetFileName(Application.ExecutablePath); var runBat = false; var runFileResults = new DicIgnoreCase <string>(); var failedUpdateFiles = new List <string>(); var failedDeleteFiles = new List <string>(); foreach (var file in filesToUpdate) { if (Constants.BatFile.Equals(file.Path, StringComparison.OrdinalIgnoreCase)) { runBat = true; } if (file.Status == UpdateRunFileStatus.Update) { var url = GetRunFileUrl(host, systemId, file.Path); var localPath = Path.Combine(runDir, file.Path); var updateSelf = file.Path.Equals(thisExeName, StringComparison.OrdinalIgnoreCase); // 自更新 OnProcessFile?.Invoke("正在安装文件:" + localPath); var success = DownloadRunFile(url, localPath, possibllyInUse: updateSelf); if (!success) { failedUpdateFiles.Add(file.Path); // 对于更新失败的文件(非新增),新的配置文件应该仍包含更新前的文件标识 if (!string.IsNullOrEmpty(file.OldTag)) { runFileResults.Add(file.Path, file.OldTag); } } else { runFileResults.Add(file.Path, file.NewTag); } } else if (file.Status == UpdateRunFileStatus.Delete) { // 删除文件 var localPath = Path.Combine(runDir, file.Path); OnProcessFile?.Invoke("正在删除文件:" + localPath); if (!DeleteRunFile(localPath)) { failedDeleteFiles.Add(file.Path); // 对于删除失败的文件,新的配置文件应该仍包含旧的文件标识 runFileResults.Add(file.Path, file.OldTag); } } OnProgress?.Invoke((++progress) * 1.0 / total); } foreach (var f in fileDiffResults.Where(f => f.Status == UpdateRunFileStatus.NotModified)) { runFileResults.Add(f.Path, f.OldTag); } localRunInfo.Ver = remoteRunInfo.Ver; localRunInfo.RunFiles = runFileResults; OnComplete?.Invoke(localRunInfo, fileDiffResults, failedUpdateFiles, failedDeleteFiles, initStart, runBat, msg); } catch (Exception ex) { if (localRunInfo != null) { LogHelper.LogErrorToServer($"客户端更新失败({msg})", ex, localRunInfo); } OnError?.Invoke(localRunInfo, ex); } }