版本号升级至2.2.6,新增版本说明弹窗功能

- 升级程序不再使用缓存文件,避免上一次下载的程序不完整
This commit is contained in:
LittleBoy 2025-07-04 11:35:30 +08:00
parent 5c52c1a87a
commit e28499b26f
12 changed files with 332 additions and 16 deletions

Binary file not shown.

View File

@ -362,6 +362,12 @@
<Compile Include="Controls\FormMessage.Designer.cs">
<DependentUpon>FormMessage.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormReadme.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormReadme.Designer.cs">
<DependentUpon>FormReadme.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormSetting.cs">
<SubType>Form</SubType>
</Compile>
@ -450,6 +456,9 @@
<EmbeddedResource Include="Controls\FormMessage.resx">
<DependentUpon>FormMessage.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormReadme.resx">
<DependentUpon>FormReadme.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormSetting.resx">
<DependentUpon>FormSetting.cs</DependentUpon>
</EmbeddedResource>

View File

@ -750,7 +750,6 @@ namespace AIProofread
public void SelectMarkById(int proofreadId, int documentId)
{
Globals.ThisAddIn.ActiveDocument?.SelectMarkById(proofreadId, false);
}

View File

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
namespace AIProofread
@ -36,8 +37,8 @@ namespace AIProofread
public class Config
{
public static readonly string APP_NAME = "AI校对王";
public static readonly string APP_VERSION = "2.2.5";
public static readonly string BuildVersion = "20250620_1532";
public static readonly string APP_VERSION = "2.2.6";
public static readonly string BuildVersion = "20250623_1757";
public static bool IS_WPS = false;
public static bool UpgradeForcedNotice = false;
public static readonly string APP_BASE_DIR = AppDomain.CurrentDomain.BaseDirectory;
@ -65,6 +66,7 @@ namespace AIProofread
public static readonly string APP_DATA_PATH = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\ai_proofread";
public static readonly string APP_LOG_PATH = APP_DATA_PATH + "\\logs\\";
public static readonly string APP_README_PATH = APP_DATA_PATH + "\\readme\\";
public static readonly string WEB_DATA_PATH = APP_DATA_PATH + "\\userdata";
/// <summary>
@ -73,6 +75,14 @@ namespace AIProofread
public static readonly string BOOKMARK_NAME_PREFIX = "ai_proofread_";
private static readonly Regex regex = new Regex("^ai_proofread_\\d+$");
public static string GetCurrentVersionReadmeCacheFile()
{
if (!Directory.Exists(APP_README_PATH))
{
Directory.CreateDirectory(APP_README_PATH);
}
return Path.Combine(APP_README_PATH, APP_VERSION + ".txt");
}
public static bool IsProofreadMark(string name)
{

View File

@ -0,0 +1,68 @@
namespace AIProofread.Controls
{
partial class FormReadme
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.WebView_ReadMe = new Microsoft.Web.WebView2.WinForms.WebView2();
((System.ComponentModel.ISupportInitialize)(this.WebView_ReadMe)).BeginInit();
this.SuspendLayout();
//
// WebView_ReadMe
//
this.WebView_ReadMe.AllowExternalDrop = true;
this.WebView_ReadMe.CreationProperties = null;
this.WebView_ReadMe.DefaultBackgroundColor = System.Drawing.Color.White;
this.WebView_ReadMe.Dock = System.Windows.Forms.DockStyle.Fill;
this.WebView_ReadMe.Location = new System.Drawing.Point(0, 0);
this.WebView_ReadMe.Name = "WebView_ReadMe";
this.WebView_ReadMe.Size = new System.Drawing.Size(600, 480);
this.WebView_ReadMe.TabIndex = 0;
this.WebView_ReadMe.ZoomFactor = 1D;
//
// FormReadme
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(600, 480);
this.Controls.Add(this.WebView_ReadMe);
this.Name = "FormReadme";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "版本更新说明";
this.TopMost = true;
this.Load += new System.EventHandler(this.FormReadme_Load);
((System.ComponentModel.ISupportInitialize)(this.WebView_ReadMe)).EndInit();
this.ResumeLayout(false);
}
#endregion
private Microsoft.Web.WebView2.WinForms.WebView2 WebView_ReadMe;
}
}

View File

@ -0,0 +1,55 @@
using AIProofread.core;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace AIProofread.Controls
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public partial class FormReadme : BaseWinForm
{
/// <summary>
/// 单例实例。
/// </summary>
private static FormReadme INSTANCE = null;
public FormReadme()
{
InitializeComponent();
// 写入缓存
File.WriteAllText(Config.GetCurrentVersionReadmeCacheFile(), DateTime.Now.ToString("yyyy-M-d"));
}
/// <summary>
/// 获取单例对象。
/// </summary>
public static FormReadme GetInstance(bool newInstance = true)
{
if (newInstance && (INSTANCE == null || INSTANCE.IsDisposed))
{
INSTANCE = new FormReadme();
}
return INSTANCE;
}
public void CloseAndDispose()
{
if (INSTANCE != null && !INSTANCE.IsDisposed)
{
INSTANCE.Close();
INSTANCE = null;
}
}
private void FormReadme_Load(object sender, EventArgs e)
{
// 初始化
InitWebView(WebView_ReadMe, Config.WebPath("version-readme"), "version-readme", () =>
{
WebView_ReadMe.CoreWebView2.AddHostObjectToScript("readme", this);
});
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -7,10 +7,10 @@ using System.Security;
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AI校对王")]
[assembly: AssemblyDescription("AI校对王 2.2.5")]
[assembly: AssemblyDescription("AI校对王 2.2.6")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("果麦文化传媒股份有限公司")]
[assembly: AssemblyProduct("AI校对王 2.2.5")]
[assembly: AssemblyProduct("AI校对王 2.2.6")]
[assembly: AssemblyCopyright("Copyright © 果麦文化传媒股份有限公司 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -33,6 +33,6 @@ using System.Security;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0")]
[assembly: AssemblyFileVersion("2.2.5.0")]
[assembly: AssemblyVersion("2.2.6.0")]
[assembly: AssemblyFileVersion("2.2.6.0")]

View File

@ -132,7 +132,7 @@ namespace AIProofread
//
this.BtnExportProofreadResult.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnExportProofreadResult.Image = global::AIProofread.Properties.Resources.icon_export;
this.BtnExportProofreadResult.Label = "导出勘误表\r\n";
this.BtnExportProofreadResult.Label = "勘误表导出\r\n";
this.BtnExportProofreadResult.Name = "BtnExportProofreadResult";
this.BtnExportProofreadResult.ShowImage = true;
this.BtnExportProofreadResult.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnExportProofreadResult_Click);
@ -162,7 +162,7 @@ namespace AIProofread
this.menuSencenDect.Items.Add(this.btnDetectionAll);
this.menuSencenDect.Items.Add(this.btnDetectionParagraph);
this.menuSencenDect.Items.Add(this.btnDetectionHistory);
this.menuSencenDect.Label = "常识性检测\r\n";
this.menuSencenDect.Label = "常识性校对助手\r\n";
this.menuSencenDect.Name = "menuSencenDect";
this.menuSencenDect.ShowImage = true;
//

View File

@ -142,6 +142,7 @@ namespace AIProofread
/// </summary>
public void ProcessLogout()
{
Globals.ThisAddIn.CloseReadmeIfShown();
IS_LOGIN = false;
currentLoginUserinfo = null;
ToggleLogin();
@ -162,12 +163,14 @@ namespace AIProofread
// 弹出登录窗口
private void btnLogin_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Bridge.bridge.ShowLoginForm(null);
}
// 注销登录
private void btnLogout_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.ActiveDocument.ShowDialog(currentLoginUserinfo.phone + " 退出AI校对王", "确定", "logout");
//Globals.ThisAddIn.ShowDialog("退出AI校对王",)
@ -180,23 +183,27 @@ namespace AIProofread
public void ShowNewVersionIcon()
{
Globals.ThisAddIn.CloseReadmeIfShown();
BtnUpdate.Image = Globals.ThisAddIn.IsWPS? Resources.icon_update_new_wps : Resources.icon_update_new;
}
private void btnOpenLexicon_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-lexicon", null);
//(new FormLexicon()).Show();
}
private void btnSetting_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-setting", null);
}
private void BtnGetContact_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
var frm = new FormContact();
Globals.ThisAddIn.ActiveDocument.RunInMainThread(() =>
{
@ -206,6 +213,7 @@ namespace AIProofread
private void BtnUpdate_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
//System.Windows.Forms.MessageBox.Show("当前插件是最新版本");
//Globals.ThisAddIn.SendMessageToWeb("upgrade", Config.APP_VERSION);
Bridge.bridge.ShowUpgradeView();
@ -213,6 +221,7 @@ namespace AIProofread
private void btnClear_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
//DocumentUtil.ClearProofreadMarks();
Globals.ThisAddIn.ActiveDocument.ShowDialog("请确认是否清除此文档的所有校对标注?", "确定", "clear-tips");
@ -225,11 +234,13 @@ namespace AIProofread
private void btnShowPane_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.ShowPanel();
}
private void btnHidePane_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.HidePanel();
}
@ -553,16 +564,19 @@ namespace AIProofread
private void ButtonLoadCache_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.ShowDialog("即将加载最近保存的进度,新的修改可能会丢失!", "确定", "load-cache");
}
private void BtnShowPanel_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-panel", "");
}
private void BtnOpenAppDir_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
// 打开日志目录
Process.Start(AppDomain.CurrentDomain.BaseDirectory);
}
@ -571,11 +585,13 @@ namespace AIProofread
private void BtnExportProofreadResult_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("export-result", "");
}
private void BtnShowVersion_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-version", "");
}
@ -583,11 +599,13 @@ namespace AIProofread
private void btnDetectionAll_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-check-all", "");
}
private void btnDetectionParagraph_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
// 获取当前选中的选区的首尾段落起始与结束位置
var start = currectSelectRange.Start; // .Paragraphs.First.Range
var end = currectSelectRange.End; // .Paragraphs.Last.Range
@ -598,6 +616,7 @@ namespace AIProofread
private void btnDetectionHistory_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.SendMessageToWeb("show-check-history", "");
}
@ -625,6 +644,7 @@ namespace AIProofread
private void BtnShowManual_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
try
{
Process.Start(Config.USER_MANUAL_URL);
@ -635,6 +655,7 @@ namespace AIProofread
private void BtnProofreadExact_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
//
Globals.ThisAddIn.ActiveDocument.CheckPanel();
Globals.ThisAddIn.SendMessageToWeb("start", "exact");
@ -642,12 +663,14 @@ namespace AIProofread
private void BtnProofreadFull_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Globals.ThisAddIn.ActiveDocument.CheckPanel();
Globals.ThisAddIn.SendMessageToWeb("start", "full");
}
private void button2_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.CloseReadmeIfShown();
Bridge.bridge.ShowLoginForm(null);
}
}

View File

@ -9,8 +9,6 @@ using UtilLib;
using AIProofread.Model;
using System.Collections.Generic;
using log4net;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.EMMA;
namespace AIProofread
@ -36,6 +34,7 @@ namespace AIProofread
/// 校对面板
/// </summary>
public ProofreadMainControl proofreadPanel;
private bool alreadyShowReadme = false;
/// <summary>
/// 工具栏
/// </summary>
@ -140,6 +139,7 @@ namespace AIProofread
//CheckPluginUpgradeInfo();
// CheckDocumentClosedTick();
// 定时检测文档是否关闭
//_timer = new System.Timers.Timer(10000);
//_timer.Elapsed += CheckDocumentClosed;
@ -376,6 +376,7 @@ namespace AIProofread
private void Application_DocumentChange()
{
ShowVersionReadme();
// 检测是否存在打开的文档
if (CurrentWordApplication.Documents.Count == 0)
{
@ -434,6 +435,7 @@ namespace AIProofread
/// <param name="Wn"></param>
private void Application_WindowActivate(Document activeDoc, Window Wn)
{
ShowVersionReadme();
Logger.Debug("WindowActivate -- " + activeDoc.Name);
if (activeDoc != null && InDocumentInList(activeDoc))
{
@ -442,6 +444,7 @@ namespace AIProofread
+ ActiveDocument?.CurrentDocument?.Name + "==》" + activeDoc.Name);
documentList.SetActiveDocument(activeDoc);
//// 设置当前文档
//ActiveDocument = document;
}
@ -501,9 +504,38 @@ namespace AIProofread
//LogHelper.Log("NewDocument" + doc.Name);
}
private void ShowVersionReadme()
{
if (alreadyShowReadme || File.Exists(Config.GetCurrentVersionReadmeCacheFile()))
{
return;
}
alreadyShowReadme = true;
FormReadme.GetInstance().Show();
//ActiveDocument?.RunInMainThread(() =>
//{
//});
}
/// <summary>
/// 如果Readme显示 则关闭
/// </summary>
public void CloseReadmeIfShown()
{
try
{
FormReadme.GetInstance(false).CloseAndDispose();
}
catch (Exception ex)
{
Logger.Error("CloseReadme Error", ex);
}
}
private void Application_DocumentOpen(Document doc)
{
//LogHelper.Log("DocumentOpen " + doc.Name);
ShowVersionReadme();
}

View File

@ -115,11 +115,11 @@ namespace updater
}
string updateFileName = UpgradeDir + Path.GetFileName(upgradeInfo.DownloadUrl);
// 判断是否已经存在升级包
if (File.Exists(updateFileName))
{
ExtractUpdatePackage();
return;
}
//if (File.Exists(updateFileName))
//{
// ExtractUpdatePackage();
// return;
//}
DownLoadFile(upgradeInfo.DownloadUrl, updateFileName);
}