using System; using Newtonsoft.Json; using System.Threading; using Microsoft.Office.Interop.Word; using System.Windows.Forms; using System.IO; using AIProofread.Controls; using UtilLib; using AIProofread.Model; using System.Collections.Generic; using log4net; using System.Threading.Tasks; using DocumentFormat.OpenXml.EMMA; namespace AIProofread { public partial class ThisAddIn { // LogManager.GetLogger(typeof(ThisAddIn)) public ILog Logger = LogHelper.GetLogger(typeof(ThisAddIn)); public static SynchronizationContext FmainThreadContext; public string AddinName = " "; /// /// 最小宽度 /// public static int MinWidth = 0; /// /// 启动路径 /// public string applicationStartupPath; /// /// 校对面板 /// public ProofreadMainControl proofreadPanel; /// /// 工具栏 /// public Ribbon1 ribbon; /// /// 当前word application /// public static Microsoft.Office.Interop.Word.Application CurrentWordApplication; ///// ///// 智能标记集合 ///// //internal SmartTagCollection VstoSmartTags; /// /// 所有文档信息 /// public DocumentList documentList = new DocumentList(); /// /// 当前文档信息 /// public DocumentInfo ActiveDocument { get { return documentList.SetActiveDocument(Application.ActiveDocument); } } /// /// 智能常识检测对话框 = new FormCommonsenseDetection() /// public FormCommonsenseDetection formCommonsenseDetection; /// /// 是否为wps /// public bool IsWPS { get; set; } public List LoginFormList = new List(); public static bool AppRunning = true; private System.Timers.Timer _timer; //public override void BeginInit() //{ // base.BeginInit(); // CurrentWordApplication = Application; // CurrentWordApplication.DocumentChange += CurrentWordApplication_DocumentChange; //} public void ShowDetection() { if (formCommonsenseDetection == null || formCommonsenseDetection.IsDisposed) { formCommonsenseDetection = new FormCommonsenseDetection(); } //formCommonsenseDetection.ShowInTaskbar = true; formCommonsenseDetection.Show(); // 显示在最前面 formCommonsenseDetection.Activate(); } public void HideDetection() { formCommonsenseDetection.Close(); formCommonsenseDetection = null; } private void ProcessApplicationException(object sender, UnhandledExceptionEventArgs e) { Logger.Error("UnhandledException", e.ExceptionObject as Exception); } private void ProcessApplicationFormException(object sender, System.Threading.ThreadExceptionEventArgs e) { Logger.Error("ProcessApplicationFormException", e.Exception); } private void ThisAddIn_Startup(object sender, System.EventArgs e) { try { InitDeviceId(); AppInitialize(); //formCommonsenseDetection.ShowInTaskbar = false; //formCommonsenseDetection.Show(); Logger.Debug("ThisAddIn_Startup Platform --> " + (IsWPS ? "WPS" : "WORD")); // 捕获全局异常 AppDomain.CurrentDomain.UnhandledException += ProcessApplicationException; System.Windows.Forms.Application.ThreadException += ProcessApplicationFormException; // 处理文档事件 Application.DocumentOpen += Application_DocumentOpen; Application.DocumentBeforeClose += Application_DocumentBeforeClose; Application.WindowActivate += Application_WindowActivate; //Application.WindowDeactivate += Application_WindowDeactivate; Application.DocumentBeforeSave += Application_DocumentBeforeSave; (Application as ApplicationEvents4_Event).NewDocument += Application_NewDocument; Application.DocumentChange += Application_DocumentChange; // 选区发生变化事件 this.Application.WindowSelectionChange += Application_WindowSelectionChange; //CheckPluginUpgradeInfo(); // CheckDocumentClosedTick(); // 定时检测文档是否关闭 //_timer = new System.Timers.Timer(10000); //_timer.Elapsed += CheckDocumentClosed; //_timer.AutoReset = true; //_timer.Enabled = true; try { // 默认已经打开了文档 直接初始化 if (Application.Documents.Count > 0 && Application.ActiveDocument != null) { Logger.Debug("ThisAddIn_Startup 开始初始化当前文档"); documentList.InitDocument(Application.ActiveDocument); // 直接初始化面板 // info.CheckPanel(); Logger.Debug("ThisAddIn_Startup 结束初始化当前文档"); } } catch (Exception ex) { Logger.Error("Initialize documentlist Error ", ex); } } catch (Exception ex1) { Logger.Error("Startup Error", ex1); } } private void Application_DocumentBeforePrint(Document Doc, ref bool Cancel) { throw new NotImplementedException(); } // 异步获取设备唯一标识 public void InitDeviceId() { System.Threading.Tasks.Task.Run(() => { try { var deviceId = Tools.GetDeviceId(); if (string.IsNullOrEmpty(deviceId)) { deviceId = Tools.GetDeviceId(); } if (!string.IsNullOrEmpty(deviceId)) { Config.DeviceId = deviceId; Logger.Info("设备唯一标识:" + deviceId); } } catch (Exception ex) { Logger.Error("InitDeviceId Error:", ex); } }); } public void CheckDocumentClosed(object sender, System.Timers.ElapsedEventArgs e) { var existsList = new List(); try { var docList = CurrentWordApplication.Documents; if (documentList.Count == 0 || docList.Count == existsList.Count) return; existsList.Clear(); foreach (Document item in docList) { existsList.Add(item); } // 检测文档是否关闭 for (int i = documentList.documentList.Count - 1; i >= 0; i--) { var item = documentList.documentList[i]; // 判断文档对象是否已经被移除 if (item.CurrentDocument == null) { documentList.Remove(item); continue; } // 可能出现另存问题 所以需要更新文件名称 //var oldName = item.fileName; //var currentName = item.CurrentDocument.FullName; //if (oldName != currentName) //{ // item.fileName = currentName; //} if (!existsList.Contains(item.CurrentDocument)) { Logger.Debug("检测到文档关闭,已移除:" + item.fileName); try { item.RunInMainThread(() => { item.Dispose(); }, true); } catch (Exception ex1) { Logger.Error("移除已关闭文档->释放面板", ex1); } try { documentList.Remove(item); } catch (Exception ex2) { Logger.Error("移除已关闭文档", ex2); } } } } catch (Exception ex) { Logger.Error("检测已关闭文档", ex); } //await System.Threading.Tasks.Task.Run(() => // { // // while (AppRunning) // { // Thread.Sleep(10000); // 暂停10s // } // }); } async void CheckPluginUpgradeInfo() { await System.Threading.Tasks.Task.Run(() => { try { // 检测升级信息 Bridge.bridge.CheckPluginUpgrade(); } catch (Exception ex) { Logger.Error("检测升级信息异常: ", ex); } }); } private void Application_DocumentBeforeSave(Document originDocument, ref bool SaveAsUI, ref bool Cancel) { //LogHelper.Log("DocumentSave", originDocument.Name + "\r\n"); if (CurrentWordApplication.Documents.Count == 0) { return; } //if (ActiveDocument == null) return; //// TODO 完成缓存保存 } //public DocumentInfo ActiveDocument()=> documentList.GetActiveDocument(); private void AppInitialize() { CurrentWordApplication = Application; // 初始化配置 InitAppByConfig(); // 主线程 FmainThreadContext = SynchronizationContext.Current; // 启动地址 applicationStartupPath = System.Windows.Forms.Application.StartupPath; Logger.Debug("applicationStartupPath --> " + applicationStartupPath); // 判断是否是WPS if (applicationStartupPath.Contains("WPS")) { Config.IS_WPS = true; IsWPS = true; try { Globals.Ribbons.Ribbon1.InitWPS(); } catch (Exception ex) { Logger.Error("Init WPS Error ", ex); } } //string verTextFile = Config.APP_BASE_DIR + Path.GetFileName("app_version.txt"); //try //{ // File.WriteAllText(verTextFile, Config.APP_VERSION); //} //catch (Exception ex) //{ // Logger.Error("Write App Version Error ", ex); //} Logger.Info("init " + (Config.IS_WPS ? "WPS" : "WORD") + " end"); } private void InitAppByConfig() { try { if (File.Exists(Config.CONFIG_FILE)) { string content = File.ReadAllText(Config.CONFIG_FILE); //LogHelper.Log("INIT", "Found app.json " + content); if (content == null || content.Length == 0) return; AppConfig config = JsonConvert.DeserializeObject(content); // 插件网址 if (!string.IsNullOrEmpty(config.AppUrl)) { Config.WEB_PATH = config.AppUrl; } // 运行环境 if (!string.IsNullOrEmpty(config.Environment)) { Config.APP_ENV = config.Environment == "dev" ? AppEnvironment.Dev : ( config.Environment == "test" ? AppEnvironment.Test : AppEnvironment.Prod ); } Config.RUN_IN_DEBUG = config.AppRunInDebug; //if (Config.APP_ENV != AppEnvironment.Prod && this.ribbon != null) //{ // this.ribbon.Ini(); //} } } catch (Exception) { } } private void Application_DocumentChange() { // 检测是否存在打开的文档 if (CurrentWordApplication.Documents.Count == 0) { return; } var currentDocument = CurrentWordApplication.ActiveDocument; Logger.Debug("DocumentChange => " + currentDocument.Name); CheckDocumentClosed(null, null); if (formCommonsenseDetection != null) { formCommonsenseDetection.SendMessageToWeb("document-change", null); } if (InDocumentInList(currentDocument)) { documentList.InitDocument(currentDocument); } //var document = documentList.InitDocument(CurrentWordApplication.ActiveDocument); //if (document == null) return; } private void Application_WindowDeactivate(Document doc, Window Wn) { //Logger.Log("Application_WindowDeactivate -- " + doc.FullName + " visible:"); //HidePanel(Doc); // 处理wps直接资源管理器新开文档面板闪烁问题 //if (IsWPS) { // this.currentDocumentTaskPane.Visible = false; //} } /// /// 判断当前文档是否在列表中 /// /// /// private bool InDocumentInList(Document doc) { if (doc == null) return false; foreach (Document item in Application.Documents) { if (item == doc) { return true; } } return false; } /// /// 激活文档 /// /// /// private void Application_WindowActivate(Document activeDoc, Window Wn) { Logger.Debug("WindowActivate -- " + activeDoc.Name); if (activeDoc != null && InDocumentInList(activeDoc)) { Logger.Debug("DocumentChange -- " + activeDoc.Name + " 修订模式: is " + activeDoc.TrackRevisions + ActiveDocument?.CurrentDocument?.Name + "==》" + activeDoc.Name); documentList.SetActiveDocument(activeDoc); //// 设置当前文档 //ActiveDocument = document; } //// 当前文档添加书签集合 //if (!allMarks.ContainsKey(activeDoc)) //{ // allMarks[activeDoc] = new Dictionary(); //} ////ShowPanel(Doc); //// 创建面板 //if (!taskPanels.ContainsKey(activeDoc)) //{ // ShowPanel(activeDoc, false); // panelsVisibleStatus.Add(activeDoc, false); //} //// 设置当前面板为新创建的面板 //this.currentDocumentTaskPane = taskPanels[activeDoc]; //if (IsWPS) //{ // HideOtherPanel(activeDoc); //} //if (panelsVisibleStatus.ContainsKey(activeDoc) && panelsVisibleStatus[activeDoc]) //{ // taskPanels[activeDoc].Visible = true; //} } /// /// 关闭文档 /// /// /// private void Application_DocumentBeforeClose(Document currentDoc, ref bool Cancel) { Logger.Debug("will close " + currentDoc.Name); var doc = documentList.Get(currentDoc); if (Config.IS_WPS && doc != null) { doc.HidePane(); } } //public void ActiveCurrentDocumentMarks(Document document) //{ // // 判断是否存在 没有的话初始化 // var currentDoc = document ?? Application.ActiveDocument ; // if (!allMarks.ContainsKey(currentDoc)) // { // allMarks[currentDoc] = new Dictionary(); // } // Bridge.marks = allMarks[currentDoc]; //} private void Application_NewDocument(Document doc) { //LogHelper.Log("NewDocument" + doc.Name); } private void Application_DocumentOpen(Document doc) { //LogHelper.Log("DocumentOpen " + doc.Name); } public int GetMinWidth() { return MinWidth; } public void Send(SendOrPostCallback d) { FmainThreadContext.Send(d, null); } private void Application_WindowSelectionChange(Selection s) { // 处理当前文档选区,用于判断是否显示常识性检测 ribbon.ParseSelectionChange(s); if (ActiveDocument == null || !s.Active) return; // 当前选区是否存在书签 if (s.Range.Start != s.Range.End || s.Bookmarks.Count == 0) return; var bookmarks = s.Bookmarks; // 获取当前选区书签的起始位置 var currentPosition = s.Range.Start; // Logger.Info("当前选区书签数量: " + s.Bookmarks.Count); // 遍历书签 找到所需的书签 foreach (Bookmark item in s.Bookmarks) { // 判断书签的选区不包含当前选中区域 if (currentPosition < item.Range.Start || currentPosition > item.Range.End) { ReleaseComObject(item); continue; } Logger.Debug("当前选区书签名称: " + item.Name + "范围:" + item.Range.Start + "," + item.Range.End); //Logger.Debug("当前选区书签内容: " + item.Range.Text); // 获取书签id int proofreadId = Config.GetBookmarkIdByName(item.Name); // 释放com对象 ReleaseComObject(item); Logger.Debug("当前选区proofreadId: " + proofreadId); if (proofreadId > 0) { //var targetRange = item.Range; //// 选中 //targetRange.Select(); //Globals.ThisAddIn.Application.ActiveWindow.ScrollIntoView(targetRange); // 只选择第一个书签 ActiveDocument?.SelectMarkById(proofreadId, true); ReleaseComObject(bookmarks); return; } // } ReleaseComObject(bookmarks); //Bridge.bridge.SelectMarkById(-1, 0); } // 释放COM对象 private void ReleaseComObject(object obj) { if (obj != null) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); } catch (Exception ex) { Logger.Error("ReleaseComObject Error", ex); } finally { obj = null; } } } public void SendMessageToWeb(string msg, object data) { // 先显示panel //var panel = this.ShowPanel(Application.ActiveDocument, true); //SendMessageToWeb(panel.Control, msg, data); ActiveDocument?.SendMessageToWeb(msg, data); } public void GlobalCallback(string callbackId, string result) { documentList.SetActiveDocument(Application.ActiveDocument)?.GlobalCallback(callbackId, result); } // 显示面板 public void ShowPanel() { documentList.SetActiveDocument(Application.ActiveDocument)?.ShowPane(); } // 隐藏面板 public void HidePanel() { documentList.SetActiveDocument(Application.ActiveDocument)?.HidePane(); } /// /// 隐藏所有面板 /// public void HideAllPanel() { this.documentList.HideAllPane(); } /// /// 显示登录窗口 /// /// public void ShowLoginForm(string action) { // 关闭之前的窗口 //if(LoginFormList.Count > 0){ // LoginFormList.ForEach(f => f.Close()); //} //LoginFormList.Add(frm); ActiveDocument?.ShowLogin(action); } /// /// 清理所有面板 /// //void ClearPanels() //{ // taskPanels.Values.ToList().ForEach(p => // { // try // { // p.Dispose(); // } // catch (Exception ex) // { // Console.WriteLine(ex.Message + "\n" + ex.StackTrace); // Logger.Log(ex.Message + "\n" + ex.StackTrace); // } // }); // taskPanels.Clear(); //} private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { // 取消捕获全局异常事件 AppDomain.CurrentDomain.UnhandledException -= ProcessApplicationException; System.Windows.Forms.Application.ThreadException -= ProcessApplicationFormException; Logger.Debug("shutdown"); documentList.Clear(); if (_timer != null) { _timer.Stop(); } } public void SyncLogout() { ribbon.ProcessLogout(); //taskPanels.Values.ToList().ForEach(p => //{ // try // { // // 同步登录失败信息 // SendMessageToWeb(p.Control, "async-logout", null); // } // catch (Exception ex) // { // Logger.Log("async-logout:", ex); // } //}); } public void SetDocumentId(Document document, int id) { var doc = documentList.Get(document); if (doc != null) doc.Id = id; } public DocumentInfo GetDocumentById(int id) { return id <= 0 ? ActiveDocument : documentList.GetById(id); } /// /// 清除所有标记 /// public void ClearAllProofreadMark() { ActiveDocument?.ClearAllProofreadMark(); //Globals.ThisAddIn.SendMessageToWeb("clear-tips", null); } public void ShowDialog(string message, string confirmText, string confirmAction) { ActiveDocument?.ShowDialog(message, confirmText, confirmAction); } public void ShowMessage(string message, int closeDelay) { ActiveDocument?.ShowMessage(message, closeDelay); } //public string LoadCacheByPath() //{ //} //public void SaveCache(string cache) //{ //} #region VSTO generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InternalStartup() { this.Startup += new System.EventHandler(ThisAddIn_Startup); this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); } public void InitProofreadCacheList(List list, Dictionary dics) { ActiveDocument?.InitProofreadCache(list, dics); } #endregion } }