/* * <root> * <operation>writeRes</operation> * <operator>supervisor</operator> * <operTime>Mon, 21 Sep 2020 11:01:56 +0800</operTime> * <requestResPath>读者/1/object/0</requestResPath> * <resPath>读者/0000000001/object/0</resPath> * <ranges>0-72044</ranges> * <totalLength>72045</totalLength> * <metadata><file mimetype="image/pjpeg" localpath="a10d0d2e-c3e7-44f4-83ab-e31f7608d429" /></metadata> * <style> * </style> * <clientAddress via="net.pipe://localhost/dp2library/xe">localhost</clientAddress> * <version>1.06</version> * </root> * */ static NormalResult TraceWriteRes( XmlDocument domLog, ProcessInfo info) { try { string strResPath = DomUtil.GetElementText(domLog.DocumentElement, "requestResPath"); if (string.IsNullOrEmpty(strResPath) == false) { var ret = PatronControl.ClearPhotoCacheFile(strResPath); if (ret == true) { WpfClientInfo.WriteInfoLog($"路径 {strResPath} 对应的照片本地缓存文件被同步过程删除"); } } return(new NormalResult()); } catch (Exception ex) { return(new NormalResult { Value = -1, ErrorInfo = $"TraceWriteRes() 出现异常: {ex.Message}" }); } }
private void MainWindow_Loaded(object sender, RoutedEventArgs e) { FaceManager.Base.Name = "人脸中心"; FaceManager.Url = "ipc://FaceChannel/FaceServer"; FaceManager.SetError += FaceManager_SetError;; FaceManager.Start(_cancelRefresh.Token); InterceptMouse.MouseClick += InterceptMouse_MouseClick; SetWindowPos(_position); // 后台自动检查更新 var task = Task.Run(() => { NormalResult result = WpfClientInfo.InstallUpdateSync(); if (result.Value == -1) { SetError("update", "自动更新出错: " + result.ErrorInfo); } else if (result.Value == 1) { SetError("update", result.ErrorInfo); // Updated?.Invoke(this, new UpdatedEventArgs { Message = result.ErrorInfo }); } else if (string.IsNullOrEmpty(result.ErrorInfo) == false) { SetError("update", result.ErrorInfo); } }); }
public static bool PatronDataExists() { try { using (BiblioCacheContext context = new BiblioCacheContext()) { context.Database.EnsureCreated(); return(context.Patrons.Any()); } } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"PatronDataExists() 出现异常: {ExceptionUtil.GetDebugText(ex)}"); return(false); } }
/* * <root> * <operation>setSystemParameter</operation> * <category>circulation</category> * <name>rightsTable</name> * <value>...</value> * <libraryCodeList> * </libraryCodeList> * <operator>supervisor</operator> * <operTime>Fri, 28 Aug 2020 12:02:28 +0800</operTime> * <clientAddress via="net.pipe://localhost/dp2library/xe">localhost</clientAddress> * <version>1.08</version> * </root> * */ static NormalResult TraceSetSystemParameter( XmlDocument domLog, ProcessInfo info) { try { string strCategory = DomUtil.GetElementText(domLog.DocumentElement, "category"); string strName = DomUtil.GetElementText(domLog.DocumentElement, "name"); if (strCategory == "circulation" && strName == "rightsTable") { // 获得读者借阅权限定义 var result = ShelfData.GetRightsTableFromServer(); if (result.Value == -1) { WpfClientInfo.WriteErrorLog($"同步获取读者借阅权限定义时出错: {result.ErrorInfo}"); // TODO: 延时后尝试重新获取? } else { string strOperTime = DomUtil.GetElementText(domLog.DocumentElement, "operTime"); // DateTime operTime = DateTimeUtil.FromRfc1123DateTimeString(strOperTime); WpfClientInfo.WriteInfoLog($"更新读者权限定义。操作日志创建时间 {strOperTime}"); } } return(new NormalResult()); } catch (Exception ex) { return(new NormalResult { Value = -1, ErrorInfo = $"TraceSetSystemParameter() 出现异常: {ex.Message}" }); } }
// 第二阶段:根据操作日志进行同步 // 注:中途遇到异常(例如 Loader 抛出异常),可能会丢失 INSERT_BATCH 条以内的日志记录写入 operlog 表 // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 public static async Task <ReplicationResult> DoReplication( string strStartDate, string strEndDate, LogType logType, // string serverVersion, CancellationToken token) { string strLastDate = ""; long last_index = -1; // -1 表示尚未处理 // bool bUserChanged = false; ProcessInfo info = new ProcessInfo(); // strStartDate 里面可能会包含 ":1-100" 这样的附加成分 StringUtil.ParseTwoPart(strStartDate, ":", out string strLeft, out string strRight); strStartDate = strLeft; if (string.IsNullOrEmpty(strStartDate) == true) { return(new ReplicationResult { Value = -1, ErrorInfo = "DoReplication() 出错: strStartDate 参数值不应为空" }); } LibraryChannel channel = App.CurrentApp.GetChannel(); var old_timeout = channel.Timeout; channel.Timeout = TimeSpan.FromSeconds(10); try { int nRet = OperLogLoader.MakeLogFileNames(strStartDate, strEndDate, true, // 是否包含扩展名 ".log" out List <string> dates, out string strWarning, out string strError); if (nRet == -1) { return(new ReplicationResult { Value = -1, ErrorInfo = strError }); } if (dates.Count > 0 && string.IsNullOrEmpty(strRight) == false) { dates[0] = dates[0] + ":" + strRight; } using (BiblioCacheContext context = new BiblioCacheContext()) { context.Database.EnsureCreated(); ProgressEstimate estimate = new ProgressEstimate(); OperLogLoader loader = new OperLogLoader { Channel = channel, Stop = null, // this.Progress; // loader.owner = this; Estimate = estimate, Dates = dates, Level = 0, AutoCache = false, CacheDir = "", LogType = logType, Filter = "setReaderInfo,borrow,return,setSystemParameter,writeRes", // 借书还书时候都会修改读者记录 // ServerVersion = serverVersion }; //TimeSpan old_timeout = channel.Timeout; //channel.Timeout = new TimeSpan(0, 2, 0); // 二分钟 // loader.Prompt += Loader_Prompt; try { // int nRecCount = 0; string strLastItemDate = ""; long lLastItemIndex = -1; // TODO: 计算遍历耗费的时间。如果太短了,要想办法让调主知道这一点,放缓重新调用的节奏,以避免 CPU 和网络资源太高 foreach (OperLogItem item in loader) { token.ThrowIfCancellationRequested(); //if (stop != null) // stop.SetMessage("正在同步 " + item.Date + " " + item.Index.ToString() + " " + estimate.Text + "..."); if (string.IsNullOrEmpty(item.Xml) == true) { goto CONTINUE; } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(item.Xml); } catch (Exception ex) { /* * if (this.HasLoaderPrompt()) * { * strError = logType.ToString() + "日志记录 " + item.Date + " " + item.Index.ToString() + " XML 装入 DOM 的时候发生错误: " + ex.Message; * MessagePromptEventArgs e = new MessagePromptEventArgs * { * MessageText = strError + "\r\n\r\n是否跳过此条继续处理?\r\n\r\n(确定: 跳过; 取消: 停止全部操作)", * IncludeOperText = true, * // + "\r\n\r\n是否跳过此条继续处理?", * Actions = "yes,cancel" * }; * Loader_Prompt(channel, e); * if (e.ResultAction == "cancel") * throw new ChannelException(channel.ErrorCode, strError); * else if (e.ResultAction == "yes") * continue; * else * { * // no 也是抛出异常。因为继续下一批代价太大 * throw new ChannelException(channel.ErrorCode, strError); * } * } * else */ throw new ChannelException(channel.ErrorCode, strError); } string strOperation = DomUtil.GetElementText(dom.DocumentElement, "operation"); if (strOperation == "setReaderInfo") { var trace_result = TraceSetReaderInfo( dom, info); if (trace_result.Value == -1) { WpfClientInfo.WriteErrorLog("同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + trace_result.ErrorInfo); } } else if (strOperation == "borrow" || strOperation == "return") { var trace_result = await TraceBorrowOrReturn( dom, info); if (trace_result.Value == -1) { WpfClientInfo.WriteErrorLog("同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + trace_result.ErrorInfo); } } else if (strOperation == "setSystemParameter") { var trace_result = TraceSetSystemParameter( dom, info); if (trace_result.Value == -1) { WpfClientInfo.WriteErrorLog("同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + trace_result.ErrorInfo); } } else if (strOperation == "writeRes") { var trace_result = TraceWriteRes( dom, info); if (trace_result.Value == -1) { WpfClientInfo.WriteErrorLog("同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + trace_result.ErrorInfo); } } else { continue; } #if NO if (nRet == -1) { strError = "同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + strError; /* * if (this.HasLoaderPrompt()) * { * MessagePromptEventArgs e = new MessagePromptEventArgs * { * MessageText = strError + "\r\n\r\n是否跳过此条继续处理?\r\n\r\n(确定: 跳过; 取消: 停止全部操作)", * IncludeOperText = true, * // + "\r\n\r\n是否跳过此条继续处理?", * Actions = "yes,cancel" * }; * Loader_Prompt(channel, e); * if (e.ResultAction == "cancel") * throw new Exception(strError); * else if (e.ResultAction == "yes") * continue; * else * { * // no 也是抛出异常。因为继续下一批代价太大 * throw new Exception(strError); * } * } * else */ throw new ChannelException(channel.ErrorCode, strError); } #endif // lProcessCount++; CONTINUE: // 便于循环外获得这些值 strLastItemDate = item.Date; lLastItemIndex = item.Index + 1; // index = 0; // 第一个日志文件后面的,都从头开始了 } // 记忆 strLastDate = strLastItemDate; last_index = lLastItemIndex; } finally { // loader.Prompt -= Loader_Prompt; channel.Timeout = old_timeout; } } return(new ReplicationResult { Value = last_index == -1 ? 0 : 1, LastDate = strLastDate, LastIndex = last_index, ProcessInfo = info }); } catch (ChannelException ex) { return(new ReplicationResult { Value = -1, ErrorInfo = ex.Message, ProcessInfo = info }); } catch (InterruptException ex) { // 2019/7/4 return(new ReplicationResult { Value = -1, ErrorInfo = ex.Message, ProcessInfo = info }); } catch (Exception ex) { string strError = "DoReplication() exception: " + ExceptionUtil.GetDebugText(ex); return(new ReplicationResult { Value = -1, ErrorInfo = strError, ProcessInfo = info }); } finally { channel.Timeout = old_timeout; App.CurrentApp.ReturnChannel(channel); } }
// 启动一般监控任务 public static void StartMonitorTask() { if (_monitorTask != null) { return; } CancellationToken token = App.CancelToken; token.Register(() => { _eventMonitor.Set(); }); _monitorTask = Task.Factory.StartNew(async() => { WpfClientInfo.WriteInfoLog("全局监控专用线程开始"); try { while (token.IsCancellationRequested == false) { // await Task.Delay(TimeSpan.FromSeconds(10)); _eventMonitor.WaitOne(_monitorIdleLength); token.ThrowIfCancellationRequested(); // 检查小票打印机状态 var check_result = CheckPosPrinter(); if (check_result.Value == -1) { App.SetError("printer", "小票打印机状态异常"); } else if (StringUtil.IsInList("paperout", check_result.ErrorCode)) { App.SetError("printer", "小票打印机缺纸"); } else if (StringUtil.IsInList("paperwillout", check_result.ErrorCode)) { App.SetError("printer", "小票打印机即将缺纸"); } else { App.SetError("printer", null); } // 检查升级绿色 dp2ssl if (_needReboot == false && StringUtil.IsDevelopMode() == false && ApplicationDeployment.IsNetworkDeployed == false && DateTime.Now - _lastUpdateTime > _updatePeriod) { WpfClientInfo.WriteInfoLog("开始自动检查升级"); // result.Value: // -1 出错 // 0 经过检查发现没有必要升级 // 1 成功 // 2 成功,但需要立即重新启动计算机才能让复制的文件生效 var update_result = await GreenInstall.GreenInstaller.InstallFromWeb(GreenInstall.GreenInstaller.dp2ssl_weburl, // "http://dp2003.com/dp2ssl/v1_dev", "c:\\dp2ssl", "delayExtract,updateGreenSetupExe,clearStateFile,debugInfo", //true, //true, token, null); if (update_result.Value == -1) { WpfClientInfo.WriteErrorLog($"自动检查升级出错: {update_result.ErrorInfo}"); } else { WpfClientInfo.WriteInfoLog($"结束自动检查升级 update_result:{update_result.ToString()}"); } // 2020/9/1 WpfClientInfo.WriteInfoLog($"InstallFromWeb() 调试信息如下:\r\n{update_result.DebugInfo}"); if (update_result.Value == 1 || update_result.Value == 2) { if (update_result.Value == 1) { App.TriggerUpdated("重启 dp2ssl(greensetup) 可使用新版本"); PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启 dp2ssl(greensetup) 时可自动升级到新版本"); } else if (update_result.Value == 2) { _needReboot = true; App.TriggerUpdated("重启计算机可使用新版本"); PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启计算机时可自动升级到新版本"); } } _lastUpdateTime = DateTime.Now; } // 2020/9/15 // 检查升级 ClickOnce dp2ssl if (StringUtil.IsDevelopMode() == false && ApplicationDeployment.IsNetworkDeployed == true && DateTime.Now - _lastUpdateTime > _updatePeriod) { try { // result.Value: // -1 出错 // 0 没有发现新版本 // 1 发现新版本,重启后可以使用新版本 NormalResult result = WpfClientInfo.InstallUpdateSync(); WpfClientInfo.WriteInfoLog($"ClickOnce 后台升级 dp2ssl 返回: {result.ToString()}"); if (result.Value == -1) { WpfClientInfo.WriteErrorLog($"升级出错: {result.ErrorInfo}"); } else if (result.Value == 1) { WpfClientInfo.WriteInfoLog($"升级成功: {result.ErrorInfo}"); App.TriggerUpdated(result.ErrorInfo); // MessageBox.Show(result.ErrorInfo); } else if (string.IsNullOrEmpty(result.ErrorInfo) == false) { WpfClientInfo.WriteInfoLog($"{result.ErrorInfo}"); } } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"后台 ClickOnce 自动升级出现异常: {ExceptionUtil.GetDebugText(ex)}"); } _lastUpdateTime = DateTime.Now; } } _monitorTask = null; } catch (OperationCanceledException) { } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"全局监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}"); App.SetError("global_monitor", $"全局监控专用线程出现异常: {ex.Message}"); } finally { WpfClientInfo.WriteInfoLog("全局监控专用线程结束"); } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }