Compare commits

...

6 Commits

Author SHA1 Message Date
2dust
0f3fc8e053 up 7.22.2 2026-05-18 17:36:05 +08:00
2dust
f7206f3405 Improve CheckUpdateModel 2026-05-18 17:32:07 +08:00
2dust
460a674ebc Add 'Check Only' update action
Introduce a new "Check Only" feature: add CheckOnlyCmd to CheckUpdateViewModel with CheckOnlyTask that queries updates (via UpdateService.CheckHasUpdateOnly) for selected cores and reports results without performing updates. Wire up a new btnCheckOnly in both Desktop and Avalonia views and bind the command. Add localized menuCheckOnly entries to multiple .resx files and update ResUI.Designer. Also shorten the pre-release label to "Check for pre-release" in resource files.
2026-05-17 19:15:57 +08:00
DHR60
e2428f2500 Add tun inbound rule (#9327) 2026-05-17 18:54:12 +08:00
DHR60
bc3cbb4277 Fix (#9325)
* Fix

* Rename tun tag
2026-05-17 18:52:42 +08:00
2dust
ac9d0a0193 Add periodic update checks and core support 2026-05-17 17:09:34 +08:00
24 changed files with 366 additions and 59 deletions

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>7.22.1</Version>
<Version>7.22.2</Version>
</PropertyGroup>
<PropertyGroup>

View File

@@ -505,6 +505,7 @@ public class Global
public static readonly List<string> InboundTags =
[
"tun",
"socks",
"socks2",
"socks3"

View File

@@ -48,6 +48,13 @@ public sealed class AppManager
}
}
public Dictionary<ECoreType, string> LastCheckUpdateResults { get; set; } = new();
public void SetLastCheckUpdateResult(ECoreType coreType, string result)
{
LastCheckUpdateResults[coreType] = result;
}
#endregion Property
#region App

View File

@@ -50,6 +50,50 @@ public sealed class CoreInfoManager
return fileName;
}
public List<ECoreType> GetCheckUpdateCoreTypes()
{
var lst = new List<ECoreType>();
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);

View File

@@ -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));
}
}

View File

@@ -3,8 +3,10 @@ namespace ServiceLib.Models.Dto;
public class CheckUpdateModel : ReactiveObject
{
public bool? IsSelected { get; set; }
public string? CoreType { get; set; }
public ECoreType? CoreType { get; set; }
[Reactive] public string? Remarks { get; set; }
public string? FileName { get; set; }
public bool? IsFinished { get; set; }
public bool IsGeoFile { get; set; }
public string CoreTypeForStorage => IsGeoFile ? "GeoFiles" : (CoreType?.ToString() ?? "");
}

View File

@@ -870,6 +870,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Only Check 的本地化字符串。
/// </summary>
public static string menuCheckOnly {
get {
return ResourceManager.GetString("menuCheckOnly", resourceCulture);
}
}
/// <summary>
/// 查找类似 Check Update 的本地化字符串。
/// </summary>
@@ -1887,6 +1896,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 {0} has a new version available: {1} 的本地化字符串。
/// </summary>
public static string MsgCheckUpdateHasNewVersion {
get {
return ResourceManager.GetString("MsgCheckUpdateHasNewVersion", resourceCulture);
}
}
/// <summary>
/// 查找类似 Core &apos;{0}&apos; does not support network type &apos;{1}&apos; 的本地化字符串。
/// </summary>
@@ -2040,6 +2058,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Not Support 的本地化字符串。
/// </summary>
public static string MsgNotSupport {
get {
return ResourceManager.GetString("MsgNotSupport", resourceCulture);
}
}
/// <summary>
/// 查找类似 Not support protocol &apos;{0}&apos; 的本地化字符串。
/// </summary>
@@ -3484,7 +3511,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 socks: local port, socks2: second local port, socks3: LAN port 的本地化字符串。
/// 查找类似 tun: TUN inbound, socks: local port, socks2: second local port, socks3: LAN port 的本地化字符串。
/// </summary>
public static string TbRoutingInboundTagTips {
get {
@@ -3925,7 +3952,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Check for pre-release updates 的本地化字符串。
/// 查找类似 Check for pre-release 的本地化字符串。
/// </summary>
public static string TbSettingsEnableCheckPreReleaseUpdate {
get {

View File

@@ -1731,4 +1731,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="menuExport2InnerUri" xml:space="preserve">
<value>Export v2rayN Internal Share Link to Clipboard</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} has a new version available: {1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>Only Check</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>Not Support</value>
</data>
</root>

View File

@@ -1728,4 +1728,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="menuExport2InnerUri" xml:space="preserve">
<value>Export v2rayN Internal Share Link to Clipboard</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} has a new version available: {1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>Only Check</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>Not Support</value>
</data>
</root>

View File

@@ -1731,4 +1731,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="menuExport2InnerUri" xml:space="preserve">
<value>Export v2rayN Internal Share Link to Clipboard</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} has a new version available: {1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>Only Check</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>Not Support</value>
</data>
</root>

View File

@@ -691,7 +691,7 @@
<value>Automatically adjust column width after subscription update</value>
</data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>Check for pre-release updates</value>
<value>Check for pre-release</value>
</data>
<data name="TbSettingsException" xml:space="preserve">
<value>Exception</value>
@@ -1336,7 +1336,7 @@
<value>Enable second mixed port</value>
</data>
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value>
<value>tun: TUN inbound, socks: local port, socks2: second local port, socks3: LAN port</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
@@ -1731,4 +1731,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="menuExport2InnerUri" xml:space="preserve">
<value>Export v2rayN Internal Share Link to Clipboard</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} has a new version available: {1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>Only Check</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>Not Support</value>
</data>
</root>

View File

@@ -1731,4 +1731,13 @@
<data name="menuExport2InnerUri" xml:space="preserve">
<value>Экспорт внутренней ссылки v2rayN в буфер обмена</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} has a new version available: {1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>Only Check</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>Not Support</value>
</data>
</root>

View File

@@ -691,7 +691,7 @@
<value>自动调整配置列宽在更新订阅后</value>
</data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>检查 Pre-Release 更新 (请谨慎启用)</value>
<value>检查 Pre-Release</value>
</data>
<data name="TbSettingsException" xml:space="preserve">
<value>例外</value>
@@ -1333,7 +1333,7 @@
<value>开启第二个本地监听端口</value>
</data>
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>Socks本地端口Socks2第二个本地端口Socks3局域网端口</value>
<value>TunTUN 入站,Socks本地端口Socks2第二个本地端口Socks3局域网端口</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主题</value>
@@ -1728,4 +1728,13 @@
<data name="menuExport2InnerUri" xml:space="preserve">
<value>导出 v2rayN 内部分享链接至剪贴板 (多选)</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} 有新版本可用:{1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>仅检查</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>不支持</value>
</data>
</root>

View File

@@ -691,7 +691,7 @@
<value>在更新訂閱後自動調整列寬</value>
</data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>檢查 Pre-Release 更新 (請謹慎啟用)</value>
<value>檢查 Pre-Release</value>
</data>
<data name="TbSettingsException" xml:space="preserve">
<value>例外</value>
@@ -1728,4 +1728,13 @@
<data name="menuExport2InnerUri" xml:space="preserve">
<value>匯出 v2rayN 內部分享連結至剪貼簿(多選)</value>
</data>
<data name="MsgCheckUpdateHasNewVersion" xml:space="preserve">
<value>{0} 有新版本可用:{1}</value>
</data>
<data name="menuCheckOnly" xml:space="preserve">
<value>僅檢查</value>
</data>
<data name="MsgNotSupport" xml:space="preserve">
<value>不支援</value>
</data>
</root>

View File

@@ -1,6 +1,6 @@
{
"type": "tun",
"tag": "tun-in",
"tag": "tun",
"interface_name": "singbox_tun",
"address": [
"172.18.0.1/30",

View File

@@ -87,8 +87,14 @@ public partial class CoreConfigSingboxService
});
_coreConfig.route.rules.Add(new()
{
protocol = ["dns"],
action = "hijack-dns"
type = "logical",
mode = "or",
action = "hijack-dns",
rules =
[
new() { port = [53] },
new() { protocol = ["dns"] },
],
});
}
else
@@ -96,7 +102,7 @@ public partial class CoreConfigSingboxService
_coreConfig.route.rules.Add(new()
{
port = [53],
action = "hijack-dns"
action = "hijack-dns",
});
}

View File

@@ -27,6 +27,7 @@ public partial class CoreConfigV2rayService
});
_coreConfig.routing.rules.Add(new()
{
inboundTag = ["tun"],
port = "53",
outboundTag = Global.DnsOutboundTag,
});

View File

@@ -100,6 +100,38 @@ public class UpdateService(Config config, Func<bool, string, Task> updateFunc)
}
}
public async Task<UpdateResult> CheckHasUpdateOnly(ECoreType type, bool preRelease)
{
if (!CoreInfoManager.Instance.IsCheckUpdateSupported(type))
{
return new UpdateResult(false, ResUI.MsgNotSupport);
}
var downloadHandle = new DownloadService();
var checkPreRelease = CoreInfoManager.Instance.GetCheckPreRelease(type, preRelease);
return await CheckUpdateAsync(downloadHandle, type, checkPreRelease);
}
public async Task<List<string>> CheckHasUpdateOnlyAll(bool preRelease)
{
var msgs = new List<string>();
foreach (var type in CoreInfoManager.Instance.GetCheckUpdateCoreTypes())
{
var result = await CheckHasUpdateOnly(type, preRelease);
if (result.Success && result.Version != null)
{
var msg = string.Format(ResUI.MsgCheckUpdateHasNewVersion, type, result.Version);
msgs.Add(msg);
AppManager.Instance.SetLastCheckUpdateResult(type, msg);
}
else
{
AppManager.Instance.SetLastCheckUpdateResult(type, result.Msg);
}
}
return msgs;
}
public async Task UpdateGeoFileAll()
{
await UpdateGeoFiles();

View File

@@ -3,12 +3,13 @@ namespace ServiceLib.ViewModels;
public class CheckUpdateViewModel : MyReactiveObject
{
private const string _geo = "GeoFiles";
private readonly string _v2rayN = ECoreType.v2rayN.ToString();
private readonly ECoreType _v2rayN = ECoreType.v2rayN;
private List<CheckUpdateModel> _lstUpdated = [];
private static readonly string _tag = "CheckUpdateViewModel";
public IObservableCollection<CheckUpdateModel> CheckUpdateModels { get; } = new ObservableCollectionExtended<CheckUpdateModel>();
public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> CheckOnlyCmd { get; }
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
public CheckUpdateViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
@@ -23,6 +24,13 @@ public class CheckUpdateViewModel : MyReactiveObject
_ = UpdateView(_v2rayN, ex.Message);
});
CheckOnlyCmd = ReactiveCommand.CreateFromTask(CheckOnly);
CheckOnlyCmd.ThrownExceptions.Subscribe(ex =>
{
Logging.SaveLog(_tag, ex);
_ = UpdateView(_v2rayN, ex.Message);
});
EnableCheckPreReleaseUpdate = _config.CheckUpdateItem.CheckPreReleaseUpdate;
this.WhenAnyValue(
@@ -37,21 +45,15 @@ 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));
}
CheckUpdateModels.Add(GetCheckUpdateModel(_geo));
CheckUpdateModels.Add(GetGeoFileCheckUpdateModel());
}
private CheckUpdateModel GetCheckUpdateModel(string coreType)
private CheckUpdateModel GetCheckUpdateModel(ECoreType coreType)
{
if (coreType == _v2rayN && Utils.IsPackagedInstall())
{
@@ -59,34 +61,53 @@ public class CheckUpdateViewModel : MyReactiveObject
{
IsSelected = false,
CoreType = coreType,
Remarks = ResUI.menuCheckUpdate + " (Not Support)",
IsGeoFile = false,
Remarks = ResUI.menuCheckUpdate + $" ({ResUI.MsgNotSupport})",
};
}
AppManager.Instance.LastCheckUpdateResults.TryGetValue(coreType, out var lastResult);
return new()
{
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(coreType) ?? true,
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(coreType.ToString()) ?? true,
CoreType = coreType,
IsGeoFile = false,
Remarks = lastResult ?? ResUI.menuCheckUpdate,
};
}
private CheckUpdateModel GetGeoFileCheckUpdateModel()
{
return new()
{
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(_geo) ?? true,
CoreType = null,
IsGeoFile = true,
Remarks = ResUI.menuCheckUpdate,
};
}
private async Task SaveSelectedCoreTypes()
{
_config.CheckUpdateItem.SelectedCoreTypes = CheckUpdateModels.Where(t => t.IsSelected == true).Select(t => t.CoreType ?? "").ToList();
_config.CheckUpdateItem.SelectedCoreTypes = CheckUpdateModels
.Where(t => t.IsSelected == true)
.Select(t => t.CoreTypeForStorage)
.ToList();
await ConfigHandler.SaveConfig(_config);
}
private async Task CheckOnly()
{
await Task.Run(CheckOnlyTask);
}
private async Task CheckUpdate()
{
await Task.Run(CheckUpdateTask);
}
private async Task CheckUpdateTask()
private async Task CheckOnlyTask()
{
_lstUpdated.Clear();
_lstUpdated = CheckUpdateModels.Where(x => x.IsSelected == true)
.Select(x => new CheckUpdateModel() { CoreType = x.CoreType }).ToList();
await SaveSelectedCoreTypes();
for (var k = CheckUpdateModels.Count - 1; k >= 0; k--)
@@ -98,7 +119,56 @@ public class CheckUpdateViewModel : MyReactiveObject
}
await UpdateView(item.CoreType, "...");
if (item.CoreType == _geo)
if (item.IsGeoFile || item.CoreType == null)
{
await UpdateView(item.CoreType, ResUI.menuCheckOnly + $" ({ResUI.MsgNotSupport})");
continue;
}
if (item.CoreType == null)
{
await UpdateView(item.CoreType, ResUI.MsgNotSupport);
continue;
}
var updateService = new UpdateService(_config, async (success, msg) => await Task.CompletedTask);
var result = await updateService.CheckHasUpdateOnly(item.CoreType.Value, EnableCheckPreReleaseUpdate);
if (result.Success && result.Version != null)
{
await UpdateView(item.CoreType, string.Format(ResUI.MsgCheckUpdateHasNewVersion, item.CoreType, result.Version));
}
else
{
await UpdateView(item.CoreType, result.Msg);
}
}
}
private async Task CheckUpdateTask()
{
_lstUpdated.Clear();
_lstUpdated = CheckUpdateModels
.Where(x => x.IsSelected == true)
.Select(x => new CheckUpdateModel()
{
CoreType = x.CoreType,
IsGeoFile = x.IsGeoFile
})
.ToList();
await SaveSelectedCoreTypes();
for (var k = CheckUpdateModels.Count - 1; k >= 0; k--)
{
var item = CheckUpdateModels[k];
if (item.IsSelected != true)
{
continue;
}
await UpdateView(item.CoreType, "...");
if (item.IsGeoFile)
{
await CheckUpdateGeo();
}
@@ -106,16 +176,16 @@ public class CheckUpdateViewModel : MyReactiveObject
{
if (Utils.IsPackagedInstall())
{
await UpdateView(_v2rayN, "Not Support");
await UpdateView(_v2rayN, ResUI.MsgNotSupport);
continue;
}
await CheckUpdateN(EnableCheckPreReleaseUpdate);
}
else if (item.CoreType == ECoreType.Xray.ToString())
else if (item.CoreType == ECoreType.Xray)
{
await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
}
else
else if (item.CoreType.HasValue)
{
await CheckUpdateCore(item, false);
}
@@ -124,7 +194,7 @@ public class CheckUpdateViewModel : MyReactiveObject
await UpdateFinished();
}
private void UpdatedPlusPlus(string coreType, string fileName)
private void UpdatedPlusPlus(ECoreType? coreType, string fileName)
{
var item = _lstUpdated.FirstOrDefault(x => x.CoreType == coreType);
if (item == null)
@@ -142,14 +212,14 @@ public class CheckUpdateViewModel : MyReactiveObject
{
async Task _updateUI(bool success, string msg)
{
await UpdateView(_geo, msg);
await UpdateView(null, msg);
if (success)
{
UpdatedPlusPlus(_geo, "");
UpdatedPlusPlus(null, "");
}
}
await new UpdateService(_config, _updateUI).UpdateGeoFileAll()
.ContinueWith(t => UpdatedPlusPlus(_geo, ""));
.ContinueWith(t => UpdatedPlusPlus(null, ""));
}
private async Task CheckUpdateN(bool preRelease)
@@ -175,13 +245,15 @@ public class CheckUpdateViewModel : MyReactiveObject
if (success)
{
await UpdateView(model.CoreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
UpdatedPlusPlus(model.CoreType, msg);
}
}
var type = (ECoreType)Enum.Parse(typeof(ECoreType), model.CoreType);
await new UpdateService(_config, _updateUI).CheckUpdateCore(type, preRelease)
.ContinueWith(t => UpdatedPlusPlus(model.CoreType, ""));
if (model.CoreType.HasValue)
{
await new UpdateService(_config, _updateUI).CheckUpdateCore(model.CoreType.Value, preRelease)
.ContinueWith(t => UpdatedPlusPlus(model.CoreType, ""));
}
}
private async Task UpdateFinished()
@@ -257,7 +329,7 @@ public class CheckUpdateViewModel : MyReactiveObject
{
foreach (var item in _lstUpdated)
{
if (item.FileName.IsNullOrEmpty())
if (item.FileName.IsNullOrEmpty() || item.IsGeoFile)
{
continue;
}
@@ -267,7 +339,9 @@ public class CheckUpdateViewModel : MyReactiveObject
{
continue;
}
var toPath = Utils.GetBinPath("", item.CoreType);
var coreTypeStr = item.CoreType?.ToString() ?? "";
var toPath = Utils.GetBinPath("", coreTypeStr);
if (fileName.Contains(".tar.gz"))
{
@@ -284,7 +358,7 @@ public class CheckUpdateViewModel : MyReactiveObject
}
else if (fileName.Contains(".gz"))
{
FileUtils.DecompressFile(fileName, toPath, item.CoreType);
FileUtils.DecompressFile(fileName, toPath, coreTypeStr);
}
else
{
@@ -296,7 +370,7 @@ public class CheckUpdateViewModel : MyReactiveObject
var filesList = new DirectoryInfo(toPath).GetFiles().Select(u => u.FullName).ToList();
foreach (var file in filesList)
{
await Utils.SetLinuxChmod(Path.Combine(toPath, item.CoreType.ToLower()));
await Utils.SetLinuxChmod(Path.Combine(toPath, coreTypeStr.ToLower()));
}
}
@@ -309,11 +383,12 @@ public class CheckUpdateViewModel : MyReactiveObject
}
}
private async Task UpdateView(string coreType, string msg)
private async Task UpdateView(ECoreType? coreType, string msg)
{
var item = new CheckUpdateModel()
{
CoreType = coreType,
IsGeoFile = coreType == null,
Remarks = msg,
};
@@ -327,7 +402,7 @@ public class CheckUpdateViewModel : MyReactiveObject
public async Task UpdateViewResult(CheckUpdateModel model)
{
var found = CheckUpdateModels.FirstOrDefault(t => t.CoreType == model.CoreType);
var found = CheckUpdateModels.FirstOrDefault(t => t.CoreType == model.CoreType && t.IsGeoFile == model.IsGeoFile);
if (found == null)
{
return;

View File

@@ -33,6 +33,12 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<Button
x:Name="btnCheckOnly"
Width="100"
Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.menuCheckOnly}" />
<Button
x:Name="btnCheckUpdate"
Width="100"
@@ -70,7 +76,7 @@
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding CoreType}" />
Text="{Binding CoreTypeForStorage}" />
<TextBlock
Grid.Column="2"
HorizontalAlignment="Left"

View File

@@ -13,6 +13,7 @@ public partial class CheckUpdateView : ReactiveUserControl<CheckUpdateViewModel>
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
});
}

View File

@@ -16,7 +16,7 @@
<DockPanel>
<Grid
Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto,Auto"
ColumnDefinitions="Auto,Auto,*"
DockPanel.Dock="Top"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<TextBlock
@@ -66,7 +66,8 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRuleTypeTips}" />
Text="{x:Static resx:ResUI.TbRuleTypeTips}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="2"
@@ -93,7 +94,10 @@
Margin="0,0,8,0"
Click="BtnSelectProfile_Click"
Content="{x:Static resx:ResUI.TbSelectProfile}" />
<TextBlock VerticalAlignment="Center" Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
<TextBlock
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}"
TextWrapping="Wrap" />
</StackPanel>
<TextBlock
@@ -115,7 +119,8 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRuleMatchingTips}" />
Text="{x:Static resx:ResUI.TbRuleMatchingTips}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="4"
@@ -135,7 +140,8 @@
Grid.Row="4"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center">
VerticalAlignment="Center"
TextWrapping="Wrap">
<HyperlinkButton Classes="WithIcon" Click="linkRuleobjectDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbRuleobjectDoc}" />
</HyperlinkButton>
@@ -160,7 +166,8 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRoutingInboundTagTips}" />
Text="{x:Static resx:ResUI.TbRoutingInboundTagTips}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="6"
@@ -181,7 +188,8 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRoutingTips}" />
Text="{x:Static resx:ResUI.TbRoutingTips}"
TextWrapping="Wrap" />
</Grid>
<StackPanel

View File

@@ -32,6 +32,13 @@
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<Button
x:Name="btnCheckOnly"
Width="100"
Margin="{StaticResource Margin8}"
Content="{x:Static resx:ResUI.menuCheckOnly}"
Style="{StaticResource DefButton}" />
<Button
x:Name="btnCheckUpdate"
Width="100"
@@ -77,7 +84,7 @@
<TextBlock
Grid.Column="1"
Style="{StaticResource ListItemTitle}"
Text="{Binding CoreType}" />
Text="{Binding CoreTypeForStorage}" />
<TextBlock
Grid.Column="2"
Style="{StaticResource ListItemSubTitle}"

View File

@@ -13,6 +13,7 @@ public partial class CheckUpdateView
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckOnlyCmd, v => v.btnCheckOnly).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
});
}