From ac9d0a019344540036314cc9d16979fdea29490e Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 17 May 2026 17:09:34 +0800 Subject: [PATCH] Add periodic update checks and core support --- v2rayN/ServiceLib/Manager/CoreInfoManager.cs | 44 +++++++++++++++++++ v2rayN/ServiceLib/Manager/TaskManager.cs | 26 +++++++++++ v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 9 ++++ v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.fr.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.hu.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.ru.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 3 ++ v2rayN/ServiceLib/Services/UpdateService.cs | 26 +++++++++++ .../ViewModels/CheckUpdateViewModel.cs | 12 ++--- 12 files changed, 129 insertions(+), 9 deletions(-) diff --git a/v2rayN/ServiceLib/Manager/CoreInfoManager.cs b/v2rayN/ServiceLib/Manager/CoreInfoManager.cs index e4b5c7f3..074342c7 100644 --- a/v2rayN/ServiceLib/Manager/CoreInfoManager.cs +++ b/v2rayN/ServiceLib/Manager/CoreInfoManager.cs @@ -50,6 +50,50 @@ public sealed class CoreInfoManager return fileName; } + public List GetCheckUpdateCoreTypes() + { + var lst = new List(); + + if (RuntimeInformation.ProcessArchitecture != Architecture.X86) + { + if (IsCheckUpdateSupported(ECoreType.v2rayN)) + { + lst.Add(ECoreType.v2rayN); + } + + if (!(Utils.IsWindows() && Environment.OSVersion.Version.Major < 10)) + { + lst.Add(ECoreType.Xray); + lst.Add(ECoreType.mihomo); + lst.Add(ECoreType.sing_box); + } + } + + return lst; + } + + public bool IsCheckUpdateSupported(ECoreType type) + { + return type switch + { + ECoreType.v2rayN => !Utils.IsPackagedInstall(), + ECoreType.Xray => true, + ECoreType.mihomo => true, + ECoreType.sing_box => true, + _ => false, + }; + } + + public bool GetCheckPreRelease(ECoreType type, bool preRelease) + { + return type switch + { + ECoreType.v2rayN => preRelease, + ECoreType.Xray => preRelease, + _ => false, + }; + } + private void InitCoreInfo() { var urlN = GetCoreUrl(ECoreType.v2rayN); diff --git a/v2rayN/ServiceLib/Manager/TaskManager.cs b/v2rayN/ServiceLib/Manager/TaskManager.cs index d1c73157..3fc64a2e 100644 --- a/v2rayN/ServiceLib/Manager/TaskManager.cs +++ b/v2rayN/ServiceLib/Manager/TaskManager.cs @@ -70,6 +70,18 @@ public class TaskManager } } + //Execute once 24 hour + if (numOfExecuted % 1440 == 1) + { + try + { + await UpdateTaskRunCheckUpdate(); + } + catch (Exception ex) + { + Logging.SaveLog("ScheduledTasks - UpdateTaskRunCheckUpdate", ex); + } + } numOfExecuted++; } } @@ -117,4 +129,18 @@ public class TaskManager }).UpdateGeoFileAll(); } } + + private async Task UpdateTaskRunCheckUpdate() + { + Logging.SaveLog("Execute check update"); + + var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask); + + var msgs = await updateService.CheckHasUpdateOnlyAll(_config.CheckUpdateItem.CheckPreReleaseUpdate); + foreach (var msg in msgs) + { + await _updateFunc?.Invoke(false, msg); + } + NoticeManager.Instance.Enqueue(string.Join("\n", msgs)); + } } diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index cab76bb5..a763358a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -1887,6 +1887,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 {0} has a new version available: {1} 的本地化字符串。 + /// + public static string MsgCheckUpdateHasNewVersion { + get { + return ResourceManager.GetString("MsgCheckUpdateHasNewVersion", resourceCulture); + } + } + /// /// 查找类似 Core '{0}' does not support network type '{1}' 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 9ac5aaa8..6dd074e9 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1731,4 +1731,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Export v2rayN Internal Share Link to Clipboard + + {0} has a new version available: {1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index bca6c2b7..59cff7c8 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1728,4 +1728,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Export v2rayN Internal Share Link to Clipboard + + {0} has a new version available: {1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index ab481d0e..0f25830a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1731,4 +1731,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Export v2rayN Internal Share Link to Clipboard + + {0} has a new version available: {1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index b80c4e56..92b9c83d 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1731,4 +1731,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Export v2rayN Internal Share Link to Clipboard + + {0} has a new version available: {1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 0eb0cb81..daf33e10 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1731,4 +1731,7 @@ Экспорт внутренней ссылки v2rayN в буфер обмена + + {0} has a new version available: {1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 4b8e0351..527d7b6b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1728,4 +1728,7 @@ 导出 v2rayN 内部分享链接至剪贴板 (多选) + + {0} 有新版本可用:{1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 1a8d6675..1aad3bfc 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1728,4 +1728,7 @@ 匯出 v2rayN 內部分享連結至剪貼簿(多選) + + {0} 有新版本可用:{1} + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayN/ServiceLib/Services/UpdateService.cs index ee5efc14..ddc75652 100644 --- a/v2rayN/ServiceLib/Services/UpdateService.cs +++ b/v2rayN/ServiceLib/Services/UpdateService.cs @@ -100,6 +100,32 @@ public class UpdateService(Config config, Func updateFunc) } } + public async Task CheckHasUpdateOnly(ECoreType type, bool preRelease) + { + if (!CoreInfoManager.Instance.IsCheckUpdateSupported(type)) + { + return new UpdateResult(false, "Not Support"); + } + + var downloadHandle = new DownloadService(); + var checkPreRelease = CoreInfoManager.Instance.GetCheckPreRelease(type, preRelease); + return await CheckUpdateAsync(downloadHandle, type, checkPreRelease); + } + + public async Task> CheckHasUpdateOnlyAll(bool preRelease) + { + var msgs = new List(); + foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes()) + { + var result = await CheckHasUpdateOnly(type, preRelease); + if (result.Success && result.Version != null) + { + msgs.Add(string.Format(ResUI.MsgCheckUpdateHasNewVersion, type, result.Version)); + } + } + return msgs; + } + public async Task UpdateGeoFileAll() { await UpdateGeoFiles(); diff --git a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs index dc31b41b..f6f98e1a 100644 --- a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs @@ -37,17 +37,11 @@ public class CheckUpdateViewModel : MyReactiveObject { CheckUpdateModels.Clear(); - if (RuntimeInformation.ProcessArchitecture != Architecture.X86) + foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes()) { - CheckUpdateModels.Add(GetCheckUpdateModel(_v2rayN)); - //Not Windows and under Win10 - if (!(Utils.IsWindows() && Environment.OSVersion.Version.Major < 10)) - { - CheckUpdateModels.Add(GetCheckUpdateModel(ECoreType.Xray.ToString())); - CheckUpdateModels.Add(GetCheckUpdateModel(ECoreType.mihomo.ToString())); - CheckUpdateModels.Add(GetCheckUpdateModel(ECoreType.sing_box.ToString())); - } + CheckUpdateModels.Add(GetCheckUpdateModel(type.ToString())); } + CheckUpdateModels.Add(GetCheckUpdateModel(_geo)); }