diff --git a/STranslate.sln b/STranslate.sln
index 44fbab2..ce58a49 100644
--- a/STranslate.sln
+++ b/STranslate.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31702.278
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "STranslate", "STranslate\STranslate.csproj", "{2597B480-185C-4D6D-94EC-8641BB6777F5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Updater\Updater.csproj", "{A49C9514-81CA-4FB6-A586-17477E4F28A8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{2597B480-185C-4D6D-94EC-8641BB6777F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2597B480-185C-4D6D-94EC-8641BB6777F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2597B480-185C-4D6D-94EC-8641BB6777F5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A49C9514-81CA-4FB6-A586-17477E4F28A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A49C9514-81CA-4FB6-A586-17477E4F28A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A49C9514-81CA-4FB6-A586-17477E4F28A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A49C9514-81CA-4FB6-A586-17477E4F28A8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/STranslate/Helper/Processhelper.cs b/STranslate/Helper/Processhelper.cs
new file mode 100644
index 0000000..c691c4a
--- /dev/null
+++ b/STranslate/Helper/Processhelper.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace STranslate.Helper
+{
+ public class ProcessHelper
+ {
+ public static bool Run(string filename, string[] args)
+ {
+ try
+ {
+ string arguments = "";
+ foreach (string arg in args)
+ {
+ arguments += $"\"{arg}\" ";
+ }
+ arguments = arguments.Trim();
+ Process process = new Process();
+ ProcessStartInfo startInfo = new ProcessStartInfo(filename, arguments);
+ process.StartInfo = startInfo;
+ process.Start();
+ return true;
+ }
+ catch (Exception)
+ {
+ //Logger.Error(ex.ToString());
+ return false;
+ }
+
+ }
+ }
+}
diff --git a/STranslate/Properties/AssemblyInfo.cs b/STranslate/Properties/AssemblyInfo.cs
index a94600f..c7abf66 100644
--- a/STranslate/Properties/AssemblyInfo.cs
+++ b/STranslate/Properties/AssemblyInfo.cs
@@ -47,6 +47,6 @@ using System.Windows;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.1.6.0")]
-[assembly: AssemblyFileVersion("0.1.6.0")]
+[assembly: AssemblyVersion("0.1.7.0")]
+[assembly: AssemblyFileVersion("0.1.7.0")]
[assembly: Guid("CE252DD8-179F-4544-9989-453F5DEA378D")]
\ No newline at end of file
diff --git a/STranslate/STranslate.csproj b/STranslate/STranslate.csproj
index 2ce6377..c3dde3d 100644
--- a/STranslate/STranslate.csproj
+++ b/STranslate/STranslate.csproj
@@ -94,6 +94,7 @@
+
diff --git a/STranslate/View/MainWindow.xaml.cs b/STranslate/View/MainWindow.xaml.cs
index a9a71d3..b0d52cd 100644
--- a/STranslate/View/MainWindow.xaml.cs
+++ b/STranslate/View/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
using STranslate.Helper;
using STranslate.ViewModel;
using System;
+using System.IO;
using System.Windows;
namespace STranslate.View
@@ -57,14 +58,17 @@ namespace STranslate.View
private MainVM vm = MainVM.Instance;
+ private string _version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+
+
public System.Windows.Forms.NotifyIcon NotifyIcon = new System.Windows.Forms.NotifyIcon();
#region TrayIcon
private void InitialTray()
{
- var app = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
- var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
- NotifyIcon.Text = $"{app} {version.Substring(0, version.Length - 2)}";
+ _version = HandleVersion(_version);
+ var app = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
+ NotifyIcon.Text = $"{app} {_version}";
NotifyIcon.Icon = new System.Drawing.Icon(Application.GetResourceStream(new Uri("Images/translate.ico", UriKind.Relative)).Stream);
NotifyIcon.Visible = true;
NotifyIcon.BalloonTipText = $"{app} already started...";
@@ -86,6 +90,9 @@ namespace STranslate.View
System.Windows.Forms.MenuItem OpenMainWinBTN = new System.Windows.Forms.MenuItem("显示主界面");
OpenMainWinBTN.Click += new EventHandler(OpenMainWin_Click);
+ System.Windows.Forms.MenuItem CheckUpdateBTN = new System.Windows.Forms.MenuItem("检查更新");
+ CheckUpdateBTN.Click += CheckUpdateBTN_Click;
+
System.Windows.Forms.MenuItem AutoStartBTN = new System.Windows.Forms.MenuItem("开机自启");
AutoStartBTN.Click += new EventHandler(AutoStart_Click);
@@ -99,12 +106,64 @@ namespace STranslate.View
ScreenshotTranslateMenuItemBTN,
CrossWordTranslateMenuItemBTN,
OpenMainWinBTN,
+ CheckUpdateBTN,
AutoStartBTN,
ExitBTN,
};
NotifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
}
+ private string HandleVersion(string version)
+ {
+ var ret = string.Empty;
+ ret = version.Substring(0, version.Length - 2);
+ var location = ret.LastIndexOf('.');
+ ret = ret.Remove(location, 1);
+ return ret;
+ }
+
+ ///
+ /// 检查更新
+ ///
+ ///
+ ///
+ private void CheckUpdateBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ string updaterExePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
+ "Updater.exe");
+ string updaterCacheExePath = Path.Combine(
+ AppDomain.CurrentDomain.BaseDirectory,
+ "Updater",
+ "Updater.exe");
+ string updateDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Updater");
+ if (!Directory.Exists(updateDirPath))
+ {
+ Directory.CreateDirectory(updateDirPath);
+ }
+
+ if (!File.Exists(updaterExePath))
+ {
+ MessageBox.Show("升级程序似乎已被删除,请手动前往发布页查看新版本");
+ return;
+ }
+ File.Copy(updaterExePath, updaterCacheExePath, true);
+
+ File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Newtonsoft.Json.dll"), Path.Combine(
+ AppDomain.CurrentDomain.BaseDirectory,
+ "Updater",
+ "Newtonsoft.Json.dll"), true);
+
+ ProcessHelper.Run(updaterCacheExePath, new string[] { _version });
+ }
+ catch (Exception ex)
+ {
+
+ MessageBox.Show($"无法正确启动检查更新程序\n{ex.Message}");
+ }
+ }
+
private void ScreenshotTranslateMenuItem_Click(object sender, EventArgs e)
{
vm.ScreenShotTranslate();
diff --git a/Updater/App.config b/Updater/App.config
new file mode 100644
index 0000000..4bfa005
--- /dev/null
+++ b/Updater/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Updater/App.xaml b/Updater/App.xaml
new file mode 100644
index 0000000..3a8b079
--- /dev/null
+++ b/Updater/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/Updater/App.xaml.cs b/Updater/App.xaml.cs
new file mode 100644
index 0000000..8c548fe
--- /dev/null
+++ b/Updater/App.xaml.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Updater
+{
+ ///
+ /// App.xaml 的交互逻辑
+ ///
+ public partial class App : Application
+ {
+ private System.Threading.Mutex mutex;
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+ // 阻止多开和用户主动启动
+ if (e.Args.Length == 0 || IsRuned())
+ {
+ Shutdown();
+ }
+
+ Activated += (s, e2) =>
+ {
+ var mainWindow = App.Current.MainWindow;
+ if (mainWindow.DataContext != null)
+ {
+ var mainViewModel = mainWindow.DataContext as MainViewModel;
+ if (string.IsNullOrEmpty(mainViewModel.Version))
+ {
+ mainViewModel.Version = e.Args[0];
+ }
+ }
+ };
+ }
+
+
+
+
+
+ #region 获取当前程序是否已运行
+ ///
+ /// 获取当前程序是否已运行
+ ///
+ private bool IsRuned()
+ {
+ bool ret;
+ mutex = new System.Threading.Mutex(true, System.Reflection.Assembly.GetEntryAssembly().ManifestModule.Name, out ret);
+ if (!ret)
+ {
+ return true;
+ }
+ return false;
+ }
+ #endregion
+ }
+}
diff --git a/Updater/GithubRelease.cs b/Updater/GithubRelease.cs
new file mode 100644
index 0000000..9e97e1d
--- /dev/null
+++ b/Updater/GithubRelease.cs
@@ -0,0 +1,111 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Updater
+{
+ public class GithubRelease
+ {
+ public class VersionInfo
+ {
+ ///
+ /// 版本标题
+ ///
+ public string Title { get; set; }
+ ///
+ /// 版本号
+ ///
+ public string Version { get; set; }
+ ///
+ /// 是否是预览版本
+ ///
+ public bool IsPre { get; set; }
+ ///
+ /// 下载路径
+ ///
+ public string DownloadUrl { get; set; }
+ ///
+ /// 版本更新内容网页链接
+ ///
+ public string HtmlUrl { get; set; }
+ }
+ public class GithubModel
+ {
+ public string tag_name { get; set; }
+ public string html_url { get; set; }
+ public string name { get; set; }
+ public bool prerelease { get; set; }
+
+ public List assets { get; set; }
+ }
+ public class GithubAssetsModel
+ {
+ public string browser_download_url { get; set; }
+ }
+ private string githubUrl;
+ private string nowVersion;
+ public VersionInfo Info { get; set; }
+
+ //public event UpdaterEventHandler RequestCompleteEvent;
+ //public event UpdaterEventHandler RequestErrorEvent;
+ //public delegate void UpdaterEventHandler(object sender, object value);
+ public GithubRelease(string githubUrl, string nowVersion)
+ {
+ this.githubUrl = githubUrl;
+ this.nowVersion = nowVersion;
+ Info = new VersionInfo();
+ }
+ public bool IsCanUpdate()
+ {
+ return !(nowVersion == Info.Version);
+ }
+ public async Task GetRequest()
+ {
+ var result = await Task.Run(() =>
+ {
+ HttpWebResponse httpWebRespones = null;
+ try
+ {
+ System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
+ HttpWebRequest httpWebRequest = WebRequest.Create(githubUrl) as HttpWebRequest;
+ httpWebRequest.Timeout = 60 * 1000;
+ httpWebRequest.ReadWriteTimeout = 60000;
+ httpWebRequest.AllowAutoRedirect = true;
+ httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36";
+ httpWebRespones = (HttpWebResponse)httpWebRequest.GetResponse();
+
+
+ using (Stream stream = httpWebRespones.GetResponseStream())
+ {
+ List lst = new List();
+ int nRead = 0;
+ while ((nRead = stream.ReadByte()) != -1) lst.Add((byte)nRead);
+ byte[] bodyBytes = lst.ToArray();
+
+ string body = Encoding.UTF8.GetString(bodyBytes, 0, bodyBytes.Length);
+
+ var data = JsonConvert.DeserializeObject(body);
+ Info.IsPre = data.prerelease;
+ Info.Title = data.name;
+ Info.Version = data.tag_name;
+ Info.DownloadUrl = data.assets[0].browser_download_url;
+ Info.HtmlUrl = data.html_url;
+ return Info;
+ }
+
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+
+ });
+ return result;
+ }
+ }
+}
diff --git a/Updater/MainViewModel.cs b/Updater/MainViewModel.cs
new file mode 100644
index 0000000..8473c5f
--- /dev/null
+++ b/Updater/MainViewModel.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Updater
+{
+ public class MainViewModel : INotifyPropertyChanged
+ {
+
+ private double _processValue;
+ public double ProcessValue { get => _processValue; set => UpdateProperty(ref _processValue, value); }
+
+ private string _version;
+ public string Version { get => _version; set => UpdateProperty(ref _version, value); }
+
+ #region notifychanged
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void UpdateProperty(ref T properValue, T newValue, [CallerMemberName] string properName = "")
+ {
+ if (object.Equals(properValue, newValue))
+ return;
+ properValue = newValue;
+ NotifyPropertyChanged(properName);
+ }
+
+ public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ #endregion
+ }
+}
diff --git a/Updater/MainWindow.xaml b/Updater/MainWindow.xaml
new file mode 100644
index 0000000..ec30920
--- /dev/null
+++ b/Updater/MainWindow.xaml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 版本号
+
+
+
+
+
+
+
+
+
+ 查看详细更新内容
+
+
+
+
+
+
+
+
+
+ 当前版本号:
+
+
+
+
diff --git a/Updater/MainWindow.xaml.cs b/Updater/MainWindow.xaml.cs
new file mode 100644
index 0000000..fb467c9
--- /dev/null
+++ b/Updater/MainWindow.xaml.cs
@@ -0,0 +1,238 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Updater
+{
+ ///
+ /// MainWindow.xaml 的交互逻辑
+ ///
+ public partial class MainWindow : Window
+ {
+ GithubRelease githubRelease;
+
+ ///
+ /// 新版本保存目录路径
+ ///
+ private string SaveDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory);
+ ///
+ /// 新版本保存名字
+ ///
+ private string SaveName = "update.zip";
+ ///
+ /// 新版本下载路径
+ ///
+ private string NewVersionZipURL;
+ ///
+ /// 新版本发布页路径
+ ///
+ private string NewVersionURL;
+ private MainViewModel _mainViewModel;
+ public MainWindow()
+ {
+ InitializeComponent();
+
+ _mainViewModel = new MainViewModel();
+
+ DataContext = _mainViewModel;
+
+ _mainViewModel.PropertyChanged += MainViewModel_PropertyChanged;
+ }
+
+ private void MainViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(_mainViewModel.Version))
+ {
+ githubRelease = new GithubRelease("https://api.github.com/repos/zggsong/stranslate/releases/latest", _mainViewModel.Version);
+
+ Check();
+ }
+ }
+ private async void Download()
+ {
+ SetStatus("正在下载新版本文件...", false);
+
+ UpdateBtn.Visibility = Visibility.Collapsed;
+ ReCheckBtn.Visibility = Visibility.Collapsed;
+ ProgressBar.Visibility = Visibility.Visible;
+ _mainViewModel.ProcessValue = 0;
+
+ var res = await Task.Run(() =>
+ {
+ try
+ {
+ // 确认保存目录
+ if (!Directory.Exists(SaveDir))
+ {
+ Directory.CreateDirectory(SaveDir);
+ }
+
+ Uri uri = new Uri(NewVersionZipURL);
+ HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
+ httpWebRequest.Timeout = 120 * 1000;
+ HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
+
+
+ long totalBytes = httpWebResponse.ContentLength;
+
+ Stream st = httpWebResponse.GetResponseStream();
+ Stream so = new FileStream(System.IO.Path.Combine(SaveDir, SaveName), FileMode.Create);
+
+ long totalDownloadedByte = 0;
+ byte[] by = new byte[1024];
+ int osize = st.Read(by, 0, (int)by.Length);
+ while (osize > 0)
+ {
+
+ totalDownloadedByte = osize + totalDownloadedByte;
+ so.Write(by, 0, osize);
+
+ osize = st.Read(by, 0, (int)by.Length);
+
+ //进度计算
+ double process = double.Parse(String.Format("{0:F}",
+ ((double)totalDownloadedByte / (double)totalBytes * 100)));
+ _mainViewModel.ProcessValue = process;
+ //Debug.WriteLine(ProcessValue);
+ }
+ //关闭资源
+ httpWebResponse.Close();
+ so.Close();
+ st.Close();
+
+ return true;
+
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ });
+
+ if (res)
+ {
+ // 准备更新
+ var process = Process.GetProcessesByName("STranslate");
+ if (process != null && process.Length > 0)
+ {
+ process[0].Kill();
+ }
+
+ SetStatus("下载完成,正在解压请勿关闭此窗口...");
+
+ string unpath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.FullName;
+
+ var unresult = await Task.Run(async () =>
+ {
+ await Task.Delay(3000);
+ return Unzip.ExtractZipFile(System.IO.Path.Combine(SaveDir, SaveName), unpath);
+ });
+ if (unresult)
+ {
+ SetStatus("更新完成!", false);
+ Process tai = new Process();
+ ProcessStartInfo startInfo = new ProcessStartInfo(System.IO.Path.Combine(unpath, "Tai.exe"));
+ tai.StartInfo = startInfo;
+ tai.Start();
+ }
+ else
+ {
+ SetStatus("解压文件时发生异常,请重试!通常情况可能是因为Tai主程序尚未退出。", false);
+ UpdateBtn.Visibility = Visibility.Visible;
+
+ }
+ }
+ else
+ {
+ //下载发生异常
+ SetStatus("下载时发生异常,请重试。", false);
+ UpdateBtn.Visibility = Visibility.Visible;
+ }
+ }
+
+
+ private async void Check()
+ {
+ NewVersionSP.Visibility = Visibility.Collapsed;
+ PreTag.Visibility = Visibility.Collapsed;
+
+ SetStatus("正在检查更新");
+ UpdateBtn.Visibility = Visibility.Collapsed;
+ ReCheckBtn.IsEnabled = false;
+
+ var info = await githubRelease.GetRequest();
+
+ if (info != null)
+ {
+ if (githubRelease.IsCanUpdate())
+ {
+ UpdateBtn.Visibility = Visibility.Visible;
+
+ NewVersionSP.Visibility = Visibility.Visible;
+ Version.Text = info.Version;
+ VersionTitle.Text = info.Title;
+ NewVersionZipURL = info.DownloadUrl;
+ NewVersionURL = info.HtmlUrl;
+ if (info.IsPre)
+ {
+ PreTag.Visibility = Visibility.Visible;
+ }
+ SetStatus("检测到新的版本!", false);
+ }
+ else
+ {
+ SetStatus("目前没有可用的更新。", false);
+ }
+ }
+ else
+ {
+ SetStatus("无法获取版本信息,请检查代理或网络。", false);
+ }
+ ReCheckBtn.IsEnabled = true;
+
+ }
+
+ private void SetStatus(string statusText, bool isLoading = true)
+ {
+ StatusLabel.Text = statusText;
+ ProgressBar.IsIndeterminate = isLoading;
+ if (isLoading)
+ {
+ ProgressBar.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ ProgressBar.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ private void ReCheckBtn_Click(object sender, RoutedEventArgs e)
+ {
+ Check();
+ }
+
+ private void UpdateBtn_Click(object sender, RoutedEventArgs e)
+ {
+ Download();
+ }
+
+ private void Hyperlink_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start(new ProcessStartInfo(NewVersionURL));
+ }
+ }
+}
diff --git a/Updater/Properties/AssemblyInfo.cs b/Updater/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f122cb0
--- /dev/null
+++ b/Updater/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("Updater")]
+[assembly: AssemblyDescription("A ready to use and ready to go translation tool")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("ZGGSONG")]
+[assembly: AssemblyProduct("Updater")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("ZGGSONG")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 CultureYouAreCodingWith
+//例如,如果您在源文件中使用的是美国英语,
+//使用的是美国英语,请将 设置为 en-US。 然后取消
+//对以下 NeutralResourceLanguage 特性的注释。 更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+ //(未在页面中找到资源时使用,
+ //或应用程序资源字典中找到时使用)
+ ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+ //(未在页面中找到资源时使用,
+ //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: Guid("54EA0FD9-3908-4A27-8AF7-B98EDCE7804E")]
diff --git a/Updater/Properties/Resources.Designer.cs b/Updater/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..9564639
--- /dev/null
+++ b/Updater/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.42000
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace Updater.Properties {
+ using System;
+
+
+ ///
+ /// 一个强类型的资源类,用于查找本地化的字符串等。
+ ///
+ // 此类是由 StronglyTypedResourceBuilder
+ // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+ // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+ // (以 /str 作为命令选项),或重新生成 VS 项目。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.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() {
+ }
+
+ ///
+ /// 返回此类使用的缓存的 ResourceManager 实例。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Updater.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 重写当前线程的 CurrentUICulture 属性,对
+ /// 使用此强类型资源类的所有资源查找执行重写。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Updater/Properties/Resources.resx b/Updater/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Updater/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Updater/Properties/Settings.Designer.cs b/Updater/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..dfcd23b
--- /dev/null
+++ b/Updater/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.42000
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace Updater.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.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;
+ }
+ }
+ }
+}
diff --git a/Updater/Properties/Settings.settings b/Updater/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/Updater/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Updater/Unzip.cs b/Updater/Unzip.cs
new file mode 100644
index 0000000..53c5438
--- /dev/null
+++ b/Updater/Unzip.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+
+namespace Updater
+{
+ public class Unzip
+ {
+ ///
+ /// 忽略的文件列表
+ ///
+ static readonly string[] IgnoreFiles = { };
+ public static bool ExtractZipFile(string zipPath, string extractPath)
+ {
+ try
+ {
+ if (!extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
+ extractPath += Path.DirectorySeparatorChar;
+
+ using (ZipArchive archive = ZipFile.OpenRead(zipPath))
+ {
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+
+ if (!IsIgnoreFile(entry.FullName))
+ {
+ // Gets the full path to ensure that relative segments are removed.
+ string destinationPath = Path.GetFullPath(Path.Combine(extractPath, entry.FullName));
+ if (!IsDir(destinationPath))
+ {
+ // 判断路径是否存在
+ string dir = Path.GetDirectoryName(destinationPath);
+ if (!Directory.Exists(dir))
+ {
+ Directory.CreateDirectory(dir);
+ }
+
+ if (File.Exists(destinationPath))
+ {
+ File.Delete(destinationPath);
+ }
+ // Ordinal match is safest, case-sensitive volumes can be mounted within volumes that
+ // are case-insensitive.
+ Debug.WriteLine($"抽取:{destinationPath}");
+ if (destinationPath.StartsWith(extractPath, StringComparison.Ordinal))
+ entry.ExtractToFile(destinationPath);
+ }
+ else
+ {
+ //创建目录
+ Directory.CreateDirectory(destinationPath);
+ }
+ }
+ }
+ return true;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 指示文件是否是忽略的
+ ///
+ ///
+ ///
+ static bool IsIgnoreFile(string fileName)
+ {
+ return (Array.IndexOf(IgnoreFiles, fileName) != -1);
+ }
+ ///
+ /// 指示路径是否是目录
+ ///
+ ///
+ ///
+ static bool IsDir(string path)
+ {
+ return path.Last() == '\\';
+ }
+ }
+}
diff --git a/Updater/Updater.csproj b/Updater/Updater.csproj
new file mode 100644
index 0000000..e1f6b28
--- /dev/null
+++ b/Updater/Updater.csproj
@@ -0,0 +1,113 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {A49C9514-81CA-4FB6-A586-17477E4F28A8}
+ WinExe
+ Updater
+ Updater
+ v4.8
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+
+
+ .allowedextension
+
+ AnyCPU
+ none
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+ ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+
+
+ MainWindow.xaml
+ Code
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Updater/packages.config b/Updater/packages.config
new file mode 100644
index 0000000..4de699c
--- /dev/null
+++ b/Updater/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file