diff --git a/Wox.Core/Updater/Release.cs b/Wox.Core/Updater/Release.cs index e2e157a943..4808ffefb1 100644 --- a/Wox.Core/Updater/Release.cs +++ b/Wox.Core/Updater/Release.cs @@ -7,5 +7,10 @@ public string download_link1 { get; set; } public string download_link2 { get; set; } public string description { get; set; } + + public override string ToString() + { + return version; + } } } \ No newline at end of file diff --git a/Wox.Core/Updater/UpdaterManager.cs b/Wox.Core/Updater/UpdaterManager.cs index c45ab02ff8..258d3c0b6f 100644 --- a/Wox.Core/Updater/UpdaterManager.cs +++ b/Wox.Core/Updater/UpdaterManager.cs @@ -1,11 +1,15 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Net; using System.Reflection; using System.Windows.Forms; using System.Windows.Threading; using NAppUpdate.Framework; using NAppUpdate.Framework.Common; using NAppUpdate.Framework.Sources; +using NAppUpdate.Framework.Tasks; using Newtonsoft.Json; using Wox.Core.i18n; using Wox.Core.UserSettings; @@ -18,9 +22,15 @@ namespace Wox.Core.Updater { private static UpdaterManager instance; private const string VersionCheckURL = "https://api.getwox.com/release/latest/"; - private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml"; + //private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml"; + private const string UpdateFeedURL = "http://127.0.0.1:8888/update.xml"; private static SemanticVersion currentVersion; + public event EventHandler PrepareUpdateReady; + public event EventHandler UpdateError; + + public Release NewRelease { get; set; } + public static UpdaterManager Instance { get @@ -57,6 +67,19 @@ namespace Wox.Core.Updater return new SemanticVersion(release.version) > CurrentVersion; } + public List GetAvailableUpdateFiles() + { + List files = new List(); + foreach (var task in UpdateManager.Instance.Tasks) + { + if (task is FileUpdateTask) + { + files.Add(((FileUpdateTask)task).LocalPath); + } + } + return files; + } + public void CheckUpdate() { string json = HttpRequest.Get(VersionCheckURL, HttpProxy.Instance); @@ -64,14 +87,15 @@ namespace Wox.Core.Updater { try { - Release newRelease = JsonConvert.DeserializeObject(json); - if (IsNewerThanCurrent(newRelease)) + NewRelease = JsonConvert.DeserializeObject(json); + if (IsNewerThanCurrent(NewRelease) && !UserSettingStorage.Instance.DontPromptUpdateMsg) { StartUpdate(); } } - catch + catch (System.Exception e) { + Log.Error(e); } } } @@ -105,45 +129,52 @@ namespace Wox.Core.Updater updManager.BeginPrepareUpdates(result => { ((UpdateProcessAsyncResult)result).EndInvoke(); - string updateReady = InternationalizationManager.Instance.GetTranslation("update_wox_update_ready"); - string updateInstall = InternationalizationManager.Instance.GetTranslation("update_wox_update_install"); - updateInstall = string.Format(updateInstall, updManager.UpdatesAvailable); - DialogResult dr = MessageBox.Show(updateInstall, updateReady, MessageBoxButtons.YesNo); - - if (dr == DialogResult.Yes) - { - - // ApplyUpdates is a synchronous method by design. Make sure to save all user work before calling - // it as it might restart your application - // get out of the way so the console window isn't obstructed - try - { - updManager.ApplyUpdates(true, UserSettingStorage.Instance.EnableUpdateLog, false); - } - catch (System.Exception e) - { - string updateError = - InternationalizationManager.Instance.GetTranslation("update_wox_update_error"); - Log.Error(e); - MessageBox.Show(updateError); - } - - updManager.CleanUp(); - } - else - { - updManager.CleanUp(); - } + OnPrepareUpdateReady(); }, null); }, null); } + public void CleanUp() + { + UpdateManager.Instance.CleanUp(); + } + + public void ApplyUpdates() + { + // ApplyUpdates is a synchronous method by design. Make sure to save all user work before calling + // it as it might restart your application + // get out of the way so the console window isn't obstructed + try + { + UpdateManager.Instance.ApplyUpdates(true, UserSettingStorage.Instance.EnableUpdateLog, false); + } + catch (System.Exception e) + { + string updateError = InternationalizationManager.Instance.GetTranslation("update_wox_update_error"); + Log.Error(e); + MessageBox.Show(updateError); + OnUpdateError(); + } + + UpdateManager.Instance.CleanUp(); + } + private IUpdateSource GetUpdateSource() { - // Normally this would be a web based source. - // But for the demo app, we prepare an in-memory source. - var source = new SimpleWebSource(UpdateFeedURL); + var source = new WoxUpdateSource(UpdateFeedURL, HttpRequest.GetWebProxy(HttpProxy.Instance)); return source; } + + protected virtual void OnPrepareUpdateReady() + { + var handler = PrepareUpdateReady; + if (handler != null) handler(this, EventArgs.Empty); + } + + protected virtual void OnUpdateError() + { + var handler = UpdateError; + if (handler != null) handler(this, EventArgs.Empty); + } } } diff --git a/Wox.Core/Updater/WoxUpdateSource.cs b/Wox.Core/Updater/WoxUpdateSource.cs new file mode 100644 index 0000000000..20b66e2f66 --- /dev/null +++ b/Wox.Core/Updater/WoxUpdateSource.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using NAppUpdate.Framework.Common; +using NAppUpdate.Framework.Sources; +using NAppUpdate.Framework.Utils; + +namespace Wox.Core.Updater +{ + internal class WoxUpdateSource : IUpdateSource + { + public IWebProxy Proxy { get; set; } + + public string FeedUrl { get; set; } + + public WoxUpdateSource(string feedUrl,IWebProxy proxy) + { + this.FeedUrl = feedUrl; + this.Proxy = proxy; + } + + private void TryResolvingHost() + { + Uri uri = new Uri(this.FeedUrl); + try + { + Dns.GetHostEntry(uri.Host); + } + catch (System.Exception ex) + { + throw new WebException(string.Format("Failed to resolve {0}. Check your connectivity.", (object)uri.Host), WebExceptionStatus.ConnectFailure); + } + } + + public string GetUpdatesFeed() + { + this.TryResolvingHost(); + string str = string.Empty; + WebRequest webRequest = WebRequest.Create(this.FeedUrl); + webRequest.Method = "GET"; + webRequest.Proxy = this.Proxy; + using (WebResponse response = webRequest.GetResponse()) + { + Stream responseStream = response.GetResponseStream(); + if (responseStream != null) + { + using (StreamReader streamReader = new StreamReader(responseStream, true)) + str = streamReader.ReadToEnd(); + } + } + return str; + } + + public bool GetData(string url, string baseUrl, Action onProgress, ref string tempLocation) + { + if (!string.IsNullOrEmpty(baseUrl) && !baseUrl.EndsWith("/")) + baseUrl += "/"; + FileDownloader fileDownloader = !Uri.IsWellFormedUriString(url, UriKind.Absolute) ? (!Uri.IsWellFormedUriString(baseUrl, UriKind.Absolute) ? (string.IsNullOrEmpty(baseUrl) ? new FileDownloader(url) : new FileDownloader(new Uri(new Uri(baseUrl), url))) : new FileDownloader(new Uri(new Uri(baseUrl, UriKind.Absolute), url))) : new FileDownloader(url); + fileDownloader.Proxy = this.Proxy; + if (string.IsNullOrEmpty(tempLocation) || !Directory.Exists(Path.GetDirectoryName(tempLocation))) + tempLocation = Path.GetTempFileName(); + return fileDownloader.DownloadToFile(tempLocation, onProgress); + } + } +} diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index 032f760103..84940b3039 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -71,6 +71,7 @@ + diff --git a/Wox.Infrastructure/Http/HttpRequest.cs b/Wox.Infrastructure/Http/HttpRequest.cs index 5c08377d6b..e80501936f 100644 --- a/Wox.Infrastructure/Http/HttpRequest.cs +++ b/Wox.Infrastructure/Http/HttpRequest.cs @@ -14,6 +14,24 @@ namespace Wox.Infrastructure.Http return Get(url, encoding, proxy); } + public static WebProxy GetWebProxy(IHttpProxy proxy) + { + if (proxy != null && proxy.Enabled && !string.IsNullOrEmpty(proxy.Server)) + { + if (string.IsNullOrEmpty(proxy.UserName) || string.IsNullOrEmpty(proxy.Password)) + { + return new WebProxy(proxy.Server, proxy.Port); + } + + return new WebProxy(proxy.Server, proxy.Port) + { + Credentials = new NetworkCredential(proxy.UserName, proxy.Password) + }; + } + + return null; + } + private static string Get(string url, string encoding, IHttpProxy proxy) { if (string.IsNullOrEmpty(url)) return string.Empty; @@ -21,20 +39,7 @@ namespace Wox.Infrastructure.Http HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "GET"; request.Timeout = 10 * 1000; - if (proxy != null && proxy.Enabled && !string.IsNullOrEmpty(proxy.Server)) - { - if (string.IsNullOrEmpty(proxy.UserName) || string.IsNullOrEmpty(proxy.Password)) - { - request.Proxy = new WebProxy(proxy.Server, proxy.Port); - } - else - { - request.Proxy = new WebProxy(proxy.Server, proxy.Port) - { - Credentials = new NetworkCredential(proxy.UserName, proxy.Password) - }; - } - } + request.Proxy = GetWebProxy(proxy); try { diff --git a/Wox/Images/update.png b/Wox/Images/update.png new file mode 100644 index 0000000000..c7e43cf0cd Binary files /dev/null and b/Wox/Images/update.png differ diff --git a/Wox/Languages/en.xaml b/Wox/Languages/en.xaml index b53fe9640a..54ad62c9a4 100644 --- a/Wox/Languages/en.xaml +++ b/Wox/Languages/en.xaml @@ -103,8 +103,14 @@ Wox got an error - Wox updates available - Wox updates are ready to install. {0} files will be added and replaced, this operation may restart Wox. Do you wish to install them now? + Wox new version V{0} is available An error occurred while trying to install software updates + Update + Cancel + This upgrade will restart Wox + Following files will be updated + Update files + Update description + \ No newline at end of file diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index a55209272e..39688d68f7 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -1,108 +1,114 @@ - - - 注册热键:{0} 失败 - 启动命令 {0} 失败 - 不是合法的Wox插件格式 - - - - Wox设置 - 通用 - 开机启动 - 失去焦点时自动隐藏Wox - 不显示新版本提示 - 语言 - - - 插件 - 浏览更多插件 - 禁用 - 触发关键字 - 插件目录 - 作者 - - - 主题 - 浏览更多主题 - 你好,Wox - 查询框字体 - 结果项字体 - 窗口模式 - 透明度 - - - 热键 - Wox激活热键 - 自定义查询热键 - 删除 - 编辑 - 增加 - 请选择一项 - 你确定要删除插件 {0} 的热键吗? - - - 代理 - 启用代理 - 服务器 - 端口 - 用户名 - 密码 - 测试代理 - 保存 - 服务器不能为空 - 端口不能为空 - 非法的端口格式 - 保存代理设置成功 - 代理设置正确 - 代理连接失败 - - - 关于 - 网站 - 版本 - 你已经激活了Wox {0} 次 - - - 旧触发关键字 - 新触发关键字 - 取消 - 确定 - 找不到指定的插件 - 新触发关键字不能为空 - 新触发关键字已经被指派给其他插件了,请重新选择一个关键字 - 成功 - 如果你不想设置触发关键字,可以使用*代替 - - - 预览 - 热键不可用,请选择一个新的热键 - 插件热键不合法 - 更新 - - - 热键不可用 - - - 版本 - 时间 - 请告诉我们如何重现此问题,以便我们进行修复 - 发送报告 - 取消 - 基本信息 - 异常信息 - 异常类型 - 异常源 - 堆栈信息 - 发送中 - 发送成功 - 发送失败 - Wox出错啦 - - - Wox更新 - Wox更新啦!{0}个文件会被添加和替换,并且在此过程中可能会重启Wox。你确定需要更新吗? - 更新Wox出错 - + + + 注册热键:{0} 失败 + 启动命令 {0} 失败 + 不是合法的Wox插件格式 + + + + Wox设置 + 通用 + 开机启动 + 失去焦点时自动隐藏Wox + 不显示新版本提示 + 语言 + + + 插件 + 浏览更多插件 + 禁用 + 触发关键字 + 插件目录 + 作者 + + + 主题 + 浏览更多主题 + 你好,Wox + 查询框字体 + 结果项字体 + 窗口模式 + 透明度 + + + 热键 + Wox激活热键 + 自定义查询热键 + 删除 + 编辑 + 增加 + 请选择一项 + 你确定要删除插件 {0} 的热键吗? + + + 代理 + 启用代理 + 服务器 + 端口 + 用户名 + 密码 + 测试代理 + 保存 + 服务器不能为空 + 端口不能为空 + 非法的端口格式 + 保存代理设置成功 + 代理设置正确 + 代理连接失败 + + + 关于 + 网站 + 版本 + 你已经激活了Wox {0} 次 + + + 旧触发关键字 + 新触发关键字 + 取消 + 确定 + 找不到指定的插件 + 新触发关键字不能为空 + 新触发关键字已经被指派给其他插件了,请重新选择一个关键字 + 成功 + 如果你不想设置触发关键字,可以使用*代替 + + + 预览 + 热键不可用,请选择一个新的热键 + 插件热键不合法 + 更新 + + + 热键不可用 + + + 版本 + 时间 + 请告诉我们如何重现此问题,以便我们进行修复 + 发送报告 + 取消 + 基本信息 + 异常信息 + 异常类型 + 异常源 + 堆栈信息 + 发送中 + 发送成功 + 发送失败 + Wox出错啦 + + + 发现Wox新版本 V{0} + 更新Wox出错 + 更新 + 取消 + 此更新需要重启Wox + 下列文件会被更新 + 更新文件 + 更新日志 + + \ No newline at end of file diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index 587eb7fd81..694cd3175a 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -1,108 +1,113 @@ - - - 註冊熱鍵:{0} 失敗 - 啟動命令 {0} 失敗 - 不是合法的Wox插件格式 - - - - Wox設置 - 通用 - 開機啟動 - 失去焦點時自動隱藏Wox - 不顯示新版本提示 - 語言 - - - 插件 - 瀏覽更多插件 - 禁用 - 觸發關鍵字 - 插件目錄 - 作者 - - - 主題 - 瀏覽更多主題 - 你好,Wox - 查詢框字體 - 結果項字體 - 窗口模式 - 透明度 - - - 熱鍵 - Wox激活熱鍵 - 自定義查詢熱鍵 - 刪除 - 編輯 - 增加 - 請選擇一項 - 你確定要刪除插件 {0} 的熱鍵嗎? - - - 代理 - 啟用代理 - 服務器 - 端口 - 用戶名 - 密碼 - 測試代理 - 保存 - 服務器不能為空 - 端口不能為空 - 非法的端口格式 - 保存代理設置成功 - 代理設置正確 - 代理連接失敗 - - - 關於 - 網站 - 版本 - 你已經激活了Wox {0} 次 - - - 舊觸發關鍵字 - 新觸發關鍵字 - 取消 - 確定 - 找不到指定的插件 - 新觸發關鍵字不能為空 - 新觸發關鍵字已經被指派給其他插件了,請重新選擇一個關鍵字 - 成功 - 如果你不想設置觸發關鍵字,可以使用*代替 - - - 預覽 - 熱鍵不可用,請選擇一個新的熱鍵 - 插件熱鍵不合法 - 更新 - - - 熱鍵不可用 - - - 版本 - 時間 - 請告訴我們如何重現此問題,以便我們進行修復 - 發送報告 - 取消 - 基本信息 - 異常信息 - 異常類型 - 異常源 - 堆棧信息 - 發送中 - 發送成功 - 發送失敗 - Wox出錯啦 - - - Wox更新 - Wox更新啦!{0}個文件會被添加和替換,並且在此過程中可能會重啟Wox。你確定需要更新嗎? - 更新Wox出錯 - + + + 註冊熱鍵:{0} 失敗 + 啟動命令 {0} 失敗 + 不是合法的Wox插件格式 + + + + Wox設置 + 通用 + 開機啟動 + 失去焦點時自動隱藏Wox + 不顯示新版本提示 + 語言 + + + 插件 + 瀏覽更多插件 + 禁用 + 觸發關鍵字 + 插件目錄 + 作者 + + + 主題 + 瀏覽更多主題 + 你好,Wox + 查詢框字體 + 結果項字體 + 窗口模式 + 透明度 + + + 熱鍵 + Wox激活熱鍵 + 自定義查詢熱鍵 + 刪除 + 編輯 + 增加 + 請選擇一項 + 你確定要刪除插件 {0} 的熱鍵嗎? + + + 代理 + 啟用代理 + 服務器 + 端口 + 用戶名 + 密碼 + 測試代理 + 保存 + 服務器不能為空 + 端口不能為空 + 非法的端口格式 + 保存代理設置成功 + 代理設置正確 + 代理連接失敗 + + + 關於 + 網站 + 版本 + 你已經激活了Wox {0} 次 + + + 舊觸發關鍵字 + 新觸發關鍵字 + 取消 + 確定 + 找不到指定的插件 + 新觸發關鍵字不能為空 + 新觸發關鍵字已經被指派給其他插件了,請重新選擇一個關鍵字 + 成功 + 如果你不想設置觸發關鍵字,可以使用*代替 + + + 預覽 + 熱鍵不可用,請選擇一個新的熱鍵 + 插件熱鍵不合法 + 更新 + + + 熱鍵不可用 + + + 版本 + 時間 + 請告訴我們如何重現此問題,以便我們進行修復 + 發送報告 + 取消 + 基本信息 + 異常信息 + 異常類型 + 異常源 + 堆棧信息 + 發送中 + 發送成功 + 發送失敗 + Wox出錯啦 + + + 發現Wox新版本 V{0} + 更新Wox出錯 + 更新 + 取消 + 此更新需要重啟Wox + 下列文件會被更新 + 更新文件 + 更新日誌 + \ No newline at end of file diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index c896f7b39f..1f408c20e4 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -238,9 +238,30 @@ namespace Wox InitProgressbarAnimation(); WindowIntelopHelper.DisableControlBox(this); + CheckUpdate(); + } + + private void CheckUpdate() + { + UpdaterManager.Instance.PrepareUpdateReady+=OnPrepareUpdateReady; + UpdaterManager.Instance.UpdateError += OnUpdateError; UpdaterManager.Instance.CheckUpdate(); } + void OnUpdateError(object sender, EventArgs e) + { + string updateError = InternationalizationManager.Instance.GetTranslation("update_wox_update_error"); + MessageBox.Show(updateError); + } + + private void OnPrepareUpdateReady(object sender, EventArgs e) + { + Dispatcher.Invoke(new Action(() => + { + new WoxUpdate().ShowDialog(); + })); + } + public void SetHotkey(string hotkeyStr, EventHandler action) { var hotkey = new HotkeyModel(hotkeyStr); diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index c6d7649a69..5102805cd0 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -66,6 +66,9 @@ False ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + ..\packages\MarkdownSharp.1.13.0.0\lib\35\MarkdownSharp.dll + False ..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll @@ -113,6 +116,9 @@ + + WoxUpdate.xaml + MSBuild:Compile Designer @@ -170,6 +176,9 @@ Designer PreserveNewest + + PreserveNewest + Designer MSBuild:Compile @@ -230,6 +239,10 @@ Designer PreserveNewest + + Designer + MSBuild:Compile + diff --git a/Wox/WoxUpdate.xaml b/Wox/WoxUpdate.xaml new file mode 100644 index 0000000000..648d196125 --- /dev/null +++ b/Wox/WoxUpdate.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wox/WoxUpdate.xaml.cs b/Wox/WoxUpdate.xaml.cs new file mode 100644 index 0000000000..3534bac0b2 --- /dev/null +++ b/Wox/WoxUpdate.xaml.cs @@ -0,0 +1,34 @@ +using System.Windows; +using MarkdownSharp; +using Wox.Core.i18n; +using Wox.Core.Updater; + +namespace Wox +{ + public partial class WoxUpdate : Window + { + public WoxUpdate() + { + InitializeComponent(); + + string newVersionAvailable = string.Format( + InternationalizationManager.Instance.GetTranslation("update_wox_update_new_version_available"), + UpdaterManager.Instance.NewRelease); + tbNewVersionAvailable.Text = newVersionAvailable; + Markdown markdown = new Markdown(); + wbDetails.NavigateToString(markdown.Transform(UpdaterManager.Instance.NewRelease.description)); + lbUpdatedFiles.ItemsSource = UpdaterManager.Instance.GetAvailableUpdateFiles(); + } + + private void btnUpdate_Click(object sender, RoutedEventArgs e) + { + UpdaterManager.Instance.ApplyUpdates(); + } + + private void btnCancel_Click(object sender, RoutedEventArgs e) + { + UpdaterManager.Instance.CleanUp(); + Close(); + } + } +} diff --git a/Wox/packages.config b/Wox/packages.config index 5e5610702f..9f1a6d32bb 100644 --- a/Wox/packages.config +++ b/Wox/packages.config @@ -1,6 +1,7 @@  +