更新程序

This commit is contained in:
LittleBoy 2024-08-20 22:43:50 +08:00
parent 9dbe1d5bf4
commit cdcbf03d92
19 changed files with 1274 additions and 0 deletions

6
updater/App.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
</configuration>

111
updater/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,111 @@
namespace updater
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.LabelLog = new System.Windows.Forms.Label();
this.ButtonUpdate = new System.Windows.Forms.Button();
this.LabelLocalVersion = new System.Windows.Forms.Label();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// LabelLog
//
this.LabelLog.BackColor = System.Drawing.SystemColors.ControlLight;
this.LabelLog.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.LabelLog.Location = new System.Drawing.Point(52, 52);
this.LabelLog.Name = "LabelLog";
this.LabelLog.Size = new System.Drawing.Size(340, 100);
this.LabelLog.TabIndex = 0;
this.LabelLog.Text = "正在检测";
this.LabelLog.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.LabelLog.Click += new System.EventHandler(this.LabelLog_Click);
//
// ButtonUpdate
//
this.ButtonUpdate.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(100)))), ((int)(((byte)(215)))));
this.ButtonUpdate.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(100)))), ((int)(((byte)(215)))));
this.ButtonUpdate.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Blue;
this.ButtonUpdate.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(100)))), ((int)(((byte)(215)))));
this.ButtonUpdate.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.ButtonUpdate.ForeColor = System.Drawing.Color.White;
this.ButtonUpdate.Location = new System.Drawing.Point(183, 198);
this.ButtonUpdate.Name = "ButtonUpdate";
this.ButtonUpdate.Size = new System.Drawing.Size(78, 31);
this.ButtonUpdate.TabIndex = 1;
this.ButtonUpdate.Text = "立即更新";
this.ButtonUpdate.UseVisualStyleBackColor = false;
this.ButtonUpdate.Click += new System.EventHandler(this.ButtonUpdate_Click);
//
// LabelLocalVersion
//
this.LabelLocalVersion.Location = new System.Drawing.Point(172, 232);
this.LabelLocalVersion.Name = "LabelLocalVersion";
this.LabelLocalVersion.Size = new System.Drawing.Size(100, 23);
this.LabelLocalVersion.TabIndex = 2;
this.LabelLocalVersion.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(52, 159);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(340, 10);
this.progressBar1.TabIndex = 3;
this.progressBar1.Visible = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(438, 286);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.LabelLocalVersion);
this.Controls.Add(this.ButtonUpdate);
this.Controls.Add(this.LabelLog);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "AI校对王更新";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label LabelLog;
private System.Windows.Forms.Button ButtonUpdate;
private System.Windows.Forms.Label LabelLocalVersion;
private System.Windows.Forms.ProgressBar progressBar1;
}
}

204
updater/Form1.cs Normal file
View File

@ -0,0 +1,204 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Web.UI.Design.WebControls;
using System.Windows.Forms;
namespace updater
{
public partial class Form1 : Form
{
private int localVersionCode = 0;
private UpdateModel model;
private static string applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
private string versionFilePath = applicationBase + Path.GetFileName("version.json");
private string updateDir = applicationBase + "update\\";
private string updateInfoUri = "https://file.wx.wm-app.xyz/jdw/latest.json";
private string updateSource;
public Form1()
{
InitializeComponent();
string source = File.Exists(versionFilePath) ? File.ReadAllText(versionFilePath) : null;
if (source != null && source.Length > 0)
{
UpdateModel update = JsonConvert.DeserializeObject<UpdateModel>(source);
this.localVersionCode = update.VersionCode;
LabelLocalVersion.Text = update.Version;
}
}
private void ButtonUpdate_Click(object sender, System.EventArgs e)
{
if (CheckHostAppRunning())
{
return;
}
progressBar1.Visible = true;
if (!Directory.Exists(updateDir))
{
Directory.CreateDirectory(updateDir);
}
string updateFileName = updateDir + Path.GetFileName(model.UpdateFile);
// 判断是否已经存在升级包
if (File.Exists(updateFileName))
{
ExtractUpdatePackage();
return;
}
DownLoadFile(model.UpdateFile, updateFileName);
}
public bool CheckHostAppRunning()
{
Process[] array = Process.GetProcesses();
foreach (Process item2 in array)
{
if (item2.ProcessName.Equals("wps"))
{
MessageBox.Show("检测到 WPS 正在运行中,请关闭后再执行更新操作");
return true;
}
else if (item2.ProcessName.Equals("WINWORD"))
{
MessageBox.Show("检测到 Word 正在运行中,请关闭后再执行更新操作");
}
}
return false;
}
private void LabelLog_Click(object sender, System.EventArgs e)
{
}
public void CheckUpdate()
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(updateInfoUri);
HttpWebResponse resp = (HttpWebResponse)httpWebRequest.GetResponse();
// 获取响应内容
if (resp.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = resp.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
updateSource = readStream.ReadToEnd();
if (updateSource == null && updateSource.Length == 0)
{
LabelLog.Text = "获取更新信息失败";
return;
}
resp.Close();
UpdateModel update = JsonConvert.DeserializeObject<UpdateModel>(updateSource);
ProcessUpdate(update);
}
}
private void ProcessUpdate(UpdateModel update)
{
LabelLog.Text = update.Log;
this.model = update;
if (update.VersionCode > this.localVersionCode)
{
ButtonUpdate.Enabled = true;
}
else
{
ButtonUpdate.Visible = false;
LabelLocalVersion.Text = "当前是最新版本";
}
}
private void Form1_Load(object sender, EventArgs e)
{
ButtonUpdate.Enabled = false;
CheckUpdate();
}
public void DownLoadFile(string url, string filename)
{
try
{
WebClient client = new WebClient();
Uri uri = new Uri(url);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
client.DownloadFileAsync(uri, filename);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke(new Action(() =>
{
progressBar1.Value = e.ProgressPercentage;
}));
}
private void DownloadFileCallback(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke(new Action(() =>
{
ExtractUpdatePackage();
}));
}
private void ExtractUpdatePackage()
{
progressBar1.Value = 100;
string zipFilePath = updateDir + Path.GetFileName(model.UpdateFile);
// 可以考虑备份旧文件
//string destinationFolder = Path.Combine(applicationBase, "update\\old");
//CopyDirectory(applicationBase, destinationFolder);
//ZipFile.ExtractToDirectory(zipFilePath, applicationBase);
using (ZipArchive zip = ZipFile.OpenRead(zipFilePath))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
// 采用覆盖模式进行解压
entry.ExtractToFile(Path.Combine(applicationBase, entry.FullName), true);
}
}
MessageBox.Show("更新完成");
// 保存日志
File.WriteAllText(versionFilePath, updateSource);
this.Close();
}
public static void CopyDirectory(string sourceFolder, string destinationFolder)
{
Directory.CreateDirectory(destinationFolder);
string moduleName = Process.GetCurrentProcess().MainModule.ModuleName;
FileSystemInfo[] fileSystemInfos = new DirectoryInfo(sourceFolder).GetFileSystemInfos();
foreach (FileSystemInfo fileSystemInfo in fileSystemInfos)
{
if (fileSystemInfo is DirectoryInfo)
{
if (fileSystemInfo.Name != "update" && fileSystemInfo.Name != "logs")
{
if (!Directory.Exists(destinationFolder + "\\" + fileSystemInfo.Name))
{
Directory.CreateDirectory(destinationFolder + "\\" + fileSystemInfo.Name);
}
CopyDirectory(fileSystemInfo.FullName, destinationFolder + "\\" + fileSystemInfo.Name);
}
}
else if (!fileSystemInfo.FullName.EndsWith(moduleName))
{
File.Copy(fileSystemInfo.FullName, destinationFolder + "\\" + fileSystemInfo.Name, overwrite: true);
}
}
}
}
}

293
updater/Form1.resx Normal file
View File

@ -0,0 +1,293 @@
<?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>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
YII=
</value>
</data>
</root>

42
updater/OfficeKiller.cs Normal file
View File

@ -0,0 +1,42 @@
using System.Diagnostics;
namespace updater
{
public class OfficeKiller
{
public void KillWordProcess()
{
Process[] processesByName = Process.GetProcessesByName("WINWORD");
foreach (Process obj in processesByName)
{
UpdateData.GetInstance().ShouldRebootMSOffice = true;
obj.Kill();
obj.WaitForExit();
}
}
public void KillExcelProcess()
{
Process[] processesByName = Process.GetProcessesByName("EXCEL");
foreach (Process obj in processesByName)
{
obj.Kill();
obj.WaitForExit();
}
}
public void KillWPSProcess()
{
Process[] processesByName = Process.GetProcessesByName("wps");
foreach (Process process in processesByName)
{
UpdateData.GetInstance().ShouldRebootWPS = true;
if (!process.HasExited)
{
process.Kill();
process.WaitForExit();
}
}
}
}
}

57
updater/OfficeStarter.cs Normal file
View File

@ -0,0 +1,57 @@
using Microsoft.Win32;
using System.Diagnostics;
namespace updater
{
public class OfficeStarter
{
public void StartWPS()
{
if (UpdateData.GetInstance().ShouldRebootWPS)
{
string text = RegistHelper.GetRegistData(Registry.CurrentUser, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Kingsoft Office", "DisplayIcon");
if (string.IsNullOrWhiteSpace(text))
{
text = RegistHelper.GetAllRegistData(RegistryHive.LocalMachine, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Kingsoft Office", "DisplayIcon");
}
if (!string.IsNullOrWhiteSpace(text))
{
text = text.Substring(0, text.LastIndexOf("WPS Office")) + "WPS Office\\ksolaunch.exe";
Process.Start(text);
}
}
}
public void StartMSOffice()
{
if (UpdateData.GetInstance().ShouldRebootMSOffice)
{
string allRegistData = RegistHelper.GetAllRegistData(RegistryHive.LocalMachine, "SOFTWARE\\Microsoft\\Office\\16.0\\Word\\InstallRoot", "Path");
//检查2016 / 2019 / 365版本路径
if (string.IsNullOrWhiteSpace(allRegistData))
{
allRegistData = RegistHelper.GetAllRegistData(RegistryHive.LocalMachine, "SOFTWARE\\Microsoft\\Office\\15.0\\Common\\InstallRoot", "Path");
// 检查2013版本路径
}
if (string.IsNullOrWhiteSpace(allRegistData))
{
allRegistData = RegistHelper.GetAllRegistData(RegistryHive.LocalMachine, "SOFTWARE\\Microsoft\\Office\\14.0\\Common\\InstallRoot", "Path");
// 检查2010版本路径
}
if (string.IsNullOrWhiteSpace(allRegistData))
{
allRegistData = RegistHelper.GetAllRegistData(RegistryHive.LocalMachine, "SOFTWARE\\Microsoft\\Office\\12.0\\Common\\InstallRoot", "Path");
//检查2007版本路径
}
if (!string.IsNullOrWhiteSpace(allRegistData))
{
allRegistData += "WINWORD.exe";
//MSOffice启动路径
Process.Start(allRegistData);
}
// 未能从注册表找到MS Office 安装路径
// 没有找到 直接不处理了
}
}
}
}

21
updater/Program.cs Normal file
View File

@ -0,0 +1,21 @@
using System;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace updater
{
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AI校对王UPDATER")]
[assembly: AssemblyDescription("AI校对王更新程序")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("果麦文化")]
[assembly: AssemblyProduct("AI校对王")]
[assembly: AssemblyCopyright("Copyright © 果麦文化 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("73ac658d-cd49-4731-8491-a7bdbc811559")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

71
updater/Properties/Resources.Designer.cs generated Normal file
View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace updater.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("updater.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?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.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: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" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</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" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

30
updater/Properties/Settings.Designer.cs generated Normal file
View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace updater.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
元素。
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
</applicationRequestMinimum>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI无需
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
-->
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>

52
updater/RegistHelper.cs Normal file
View File

@ -0,0 +1,52 @@
using Microsoft.Win32;
namespace updater
{
internal class RegistHelper
{
public static string GetRegistData(RegistryKey rtype, string path, string name)
{
RegistryKey registryKey = rtype.OpenSubKey(path, writable: false);
if (registryKey != null)
{
if (registryKey.GetValue(name) != null)
{
return registryKey.GetValue(name).ToString();
}
return string.Empty;
}
return string.Empty;
}
public static string GetAllRegistData(RegistryHive rtype, string path, string name)
{
RegistryKey registryKey = RegistryKey.OpenBaseKey(rtype, RegistryView.Registry32).OpenSubKey(path);
if (registryKey == null)
{
registryKey = RegistryKey.OpenBaseKey(rtype, RegistryView.Registry64).OpenSubKey(path);
}
if (registryKey != null)
{
return registryKey.GetValue(name).ToString();
}
return string.Empty;
}
public static void WriteCURegedit(string name, string tovalue)
{
Registry.CurrentUser.OpenSubKey("SOFTWARE", writable: true).CreateSubKey("mine\\WordAddInTest1").SetValue(name, tovalue);
}
public static void DeleteCURegist(string name)
{
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE", writable: true).OpenSubKey("mine\\WordAddInTest1", writable: true);
string[] subKeyNames = registryKey.GetSubKeyNames();
for (int i = 0; i < subKeyNames.Length; i++)
{
if (subKeyNames[i] == name)
{
registryKey.DeleteSubKeyTree(name);
}
}
}
}
}

22
updater/UpdateData.cs Normal file
View File

@ -0,0 +1,22 @@
namespace updater
{
public class UpdateData
{
private static UpdateData instance;
public string CurrentVersion { get; set; }
public string LatestVersion { get; set; }
public bool ShouldRebootMSOffice { get; set; }
public bool ShouldRebootWPS { get; set; }
public static UpdateData GetInstance()
{
if (instance == null)
{
instance = new UpdateData();
}
return instance;
}
}
}

10
updater/UpdateModel.cs Normal file
View File

@ -0,0 +1,10 @@
namespace updater
{
public class UpdateModel
{
public int VersionCode { get; set; }
public string Version { get; set; }
public string Log { get; set; }
public string UpdateFile { get; set; }
}
}

BIN
updater/av802-h1xg6-001.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

4
updater/packages.config Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net462" />
</packages>

118
updater/updater.csproj Normal file
View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{73AC658D-CD49-4731-8491-A7BDBC811559}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>updater</RootNamespace>
<AssemblyName>updater</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>av802-h1xg6-001.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>false</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="AntdUI, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>D:\libs\CSharp_AntdUI\net46\AntdUI.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Design" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="OfficeKiller.cs" />
<Compile Include="OfficeStarter.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RegistHelper.cs" />
<Compile Include="UpdateData.cs" />
<Compile Include="UpdateModel.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="av802-h1xg6-001.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>