Optimize speed test

This commit is contained in:
2dust 2023-02-08 19:20:44 +08:00
parent dfb6cef364
commit d014724a2d
17 changed files with 285 additions and 53 deletions

View file

@ -0,0 +1,89 @@
using Downloader;
using System.Net;
namespace v2rayN.Base
{
internal class DownloaderHelper
{
private static readonly Lazy<DownloaderHelper> _instance = new Lazy<DownloaderHelper>(() => new());
public static DownloaderHelper Instance => _instance.Value;
public DownloaderHelper()
{
}
public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(timeout * 1000);
var downloadOpt = new DownloadConfiguration()
{
Timeout = timeout * 1000,
MaxTryAgainOnFailover = 2,
RequestConfiguration =
{
Timeout= timeout * 1000,
Proxy = webProxy
}
};
DateTime totalDatetime = DateTime.Now;
int totalSecond = 0;
var hasValue = false;
double maxSpeed = 0;
var downloader = new DownloadService(downloadOpt);
//downloader.DownloadStarted += (sender, value) =>
//{
// if (progress != null)
// {
// progress.Report("Start download data...");
// }
//};
downloader.DownloadProgressChanged += (sender, value) =>
{
TimeSpan ts = (DateTime.Now - totalDatetime);
if (progress != null && ts.Seconds > totalSecond)
{
hasValue = true;
totalSecond = ts.Seconds;
if (value.BytesPerSecondSpeed > maxSpeed)
{
maxSpeed = value.BytesPerSecondSpeed;
var speed = (maxSpeed / 1000 / 1000).ToString("#0.0");
progress.Report(speed);
}
}
};
downloader.DownloadFileCompleted += (sender, value) =>
{
if (progress != null)
{
if (!hasValue && value.Error != null)
{
progress.Report(value.Error?.Message);
}
}
};
progress.Report("......");
await downloader.DownloadFileTaskAsync(address: url, cancellationToken: cancellationToken.Token);
//var stream = await downloader.DownloadFileTaskAsync(url);
//using (StreamReader reader = new StreamReader(stream))
//{
// string text = reader.ReadToEnd();
// stream.Dispose();
//}
downloader.Dispose();
downloader = null;
downloadOpt = null;
}
}
}

View file

@ -17,7 +17,6 @@
public const string tuicCoreUrl = "https://github.com/EAimTY/tuic/releases"; public const string tuicCoreUrl = "https://github.com/EAimTY/tuic/releases";
public const string singboxCoreUrl = "https://github.com/SagerNet/sing-box/releases"; public const string singboxCoreUrl = "https://github.com/SagerNet/sing-box/releases";
public const string geoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat"; public const string geoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat";
public const string SpeedTestUrl = @"http://cachefly.cachefly.net/10mb.test";
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204"; public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/"; public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
@ -116,6 +115,7 @@
public static readonly List<string> TunMtus = new List<string> { "9000", "1500" }; public static readonly List<string> TunMtus = new List<string> { "9000", "1500" };
public static readonly List<string> TunStacks = new List<string> { "gvisor", "system" }; public static readonly List<string> TunStacks = new List<string> { "gvisor", "system" };
public static readonly List<string> PresetMsgFilters = new List<string> { "^(?!.*proxy).*$", "^(?!.*direct).*$", "" }; public static readonly List<string> PresetMsgFilters = new List<string> { "^(?!.*proxy).*$", "^(?!.*direct).*$", "" };
public static readonly List<string> SpeedTestUrls = new List<string> { @"http://cachefly.cachefly.net/100mb.test", @"http://cachefly.cachefly.net/10mb.test" };
#endregion #endregion

View file

@ -150,14 +150,6 @@ namespace v2rayN.Handler
{ {
config.constItem = new ConstItem(); config.constItem = new ConstItem();
} }
if (Utils.IsNullOrEmpty(config.constItem.speedTestUrl))
{
config.constItem.speedTestUrl = Global.SpeedTestUrl;
}
if (Utils.IsNullOrEmpty(config.constItem.speedPingTestUrl))
{
config.constItem.speedPingTestUrl = Global.SpeedPingTestUrl;
}
if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions)) if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions))
{ {
config.constItem.defIEProxyExceptions = Global.IEProxyExceptions; config.constItem.defIEProxyExceptions = Global.IEProxyExceptions;
@ -167,6 +159,23 @@ namespace v2rayN.Handler
// config.remoteDNS = "1.1.1.1"; // config.remoteDNS = "1.1.1.1";
//} //}
if (config.speedTestItem == null)
{
config.speedTestItem = new();
}
if (config.speedTestItem.speedTestTimeout < 10)
{
config.speedTestItem.speedTestTimeout = 10;
}
if (Utils.IsNullOrEmpty(config.speedTestItem.speedTestUrl))
{
config.speedTestItem.speedTestUrl = Global.SpeedTestUrls[0];
}
if (Utils.IsNullOrEmpty(config.speedTestItem.speedPingTestUrl))
{
config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrl;
}
if (config.statisticsFreshRate > 100 || config.statisticsFreshRate < 1) if (config.statisticsFreshRate > 100 || config.statisticsFreshRate < 1)
{ {
config.statisticsFreshRate = 1; config.statisticsFreshRate = 1;

View file

@ -33,20 +33,13 @@ namespace v2rayN.Handler
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> update) public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> update)
{ {
var hasValue = false;
try try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13); Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
var client = new HttpClient(new SocketsHttpHandler()
{
Proxy = webProxy
});
var progress = new Progress<string>(); var progress = new Progress<string>();
progress.ProgressChanged += (sender, value) => progress.ProgressChanged += (sender, value) =>
{ {
hasValue = true;
if (update != null) if (update != null)
{ {
string msg = $"{value}"; string msg = $"{value}";
@ -54,16 +47,12 @@ namespace v2rayN.Handler
} }
}; };
var cancellationToken = new CancellationTokenSource(); await DownloaderHelper.Instance.DownloadDataAsync4Speed(webProxy,
cancellationToken.CancelAfter(downloadTimeout * 1000);
await HttpClientHelper.GetInstance().DownloadDataAsync4Speed(client,
url, url,
progress, progress,
cancellationToken.Token); downloadTimeout);
} }
catch (Exception ex) catch (Exception ex)
{
if (!hasValue)
{ {
update(false, ex.Message); update(false, ex.Message);
if (ex.InnerException != null) if (ex.InnerException != null)
@ -71,7 +60,6 @@ namespace v2rayN.Handler
update(false, ex.InnerException.Message); update(false, ex.InnerException.Message);
} }
} }
}
return 0; return 0;
} }
@ -196,7 +184,7 @@ namespace v2rayN.Handler
try try
{ {
var config = LazyConfig.Instance.GetConfig(); var config = LazyConfig.Instance.GetConfig();
string status = GetRealPingTime(config.constItem.speedPingTestUrl, webProxy, 10, out int responseTime); string status = GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10, out int responseTime);
bool noError = Utils.IsNullOrEmpty(status); bool noError = Utils.IsNullOrEmpty(status);
return noError ? responseTime : -1; return noError ? responseTime : -1;
} }

View file

@ -195,10 +195,10 @@ namespace v2rayN.Handler
private async Task RunSpeedTestAsync() private async Task RunSpeedTestAsync()
{ {
int pid = -1; int pid = -1;
if (_actionType == ESpeedActionType.Mixedtest) //if (_actionType == ESpeedActionType.Mixedtest)
{ //{
_selecteds = _selecteds.OrderBy(t => t.delay).ToList(); // _selecteds = _selecteds.OrderBy(t => t.delay).ToList();
} //}
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds); pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
if (pid < 0) if (pid < 0)
@ -207,10 +207,11 @@ namespace v2rayN.Handler
return; return;
} }
string url = _config.constItem.speedTestUrl; string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new DownloadHandle(); DownloadHandle downloadHandle = new DownloadHandle();
var timeout = 8;
foreach (var it in _selecteds) foreach (var it in _selecteds)
{ {
if (!it.allowTest) if (!it.allowTest)
@ -221,11 +222,11 @@ namespace v2rayN.Handler
{ {
continue; continue;
} }
if (it.delay < 0) //if (it.delay < 0)
{ //{
UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip); // UpdateFunc(it.indexId, "", ResUI.SpeedtestingSkip);
continue; // continue;
} //}
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1"); _ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
var item = LazyConfig.Instance.GetProfileItem(it.indexId); var item = LazyConfig.Instance.GetProfileItem(it.indexId);
@ -250,18 +251,71 @@ namespace v2rayN.Handler
} }
UpdateFunc("", ResUI.SpeedtestingCompleted); UpdateFunc("", ResUI.SpeedtestingCompleted);
} }
private async Task RunSpeedTestMulti()
{
int pid = -1;
pid = _coreHandler.LoadCoreConfigString(_config, _selecteds);
if (pid < 0)
{
UpdateFunc("", ResUI.FailedToRunCore);
return;
}
string url = _config.speedTestItem.speedTestUrl;
var timeout = _config.speedTestItem.speedTestTimeout;
DownloadHandle downloadHandle = new DownloadHandle();
foreach (var it in _selecteds)
{
if (!it.allowTest)
{
continue;
}
if (it.configType == EConfigType.Custom)
{
continue;
}
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", "-1");
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
if (item is null) continue;
WebProxy webProxy = new WebProxy(Global.Loopback, it.port);
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
{
decimal.TryParse(msg, out decimal dec);
if (dec > 0)
{
_ = LazyConfig.Instance.SetTestResult(it.indexId, "", msg);
}
UpdateFunc(it.indexId, "", msg);
});
Thread.Sleep(2000);
}
Thread.Sleep((timeout + 2) * 1000);
if (pid > 0)
{
_coreHandler.CoreStopPid(pid);
}
UpdateFunc("", ResUI.SpeedtestingCompleted);
}
private async Task RunMixedtestAsync() private async Task RunMixedtestAsync()
{ {
await RunRealPing(); await RunRealPing();
Thread.Sleep(1000); Thread.Sleep(1000);
await RunSpeedTestAsync(); await RunSpeedTestMulti();
} }
public string GetRealPingTime(DownloadHandle downloadHandle, WebProxy webProxy) public string GetRealPingTime(DownloadHandle downloadHandle, WebProxy webProxy)
{ {
string status = downloadHandle.GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, 10, out int responseTime); string status = downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10, out int responseTime);
//string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status; //string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
return FormatOut(Utils.IsNullOrEmpty(status) ? responseTime : -1, Global.DelayUnit); return FormatOut(Utils.IsNullOrEmpty(status) ? responseTime : -1, Global.DelayUnit);
} }

View file

@ -152,6 +152,7 @@
public GrpcItem grpcItem { get; set; } public GrpcItem grpcItem { get; set; }
public UIItem uiItem { get; set; } public UIItem uiItem { get; set; }
public ConstItem constItem { get; set; } public ConstItem constItem { get; set; }
public SpeedTestItem speedTestItem { get; set; }
public List<InItem> inbound { get; set; } public List<InItem> inbound { get; set; }
public List<KeyEventItem> globalHotkeys { get; set; } public List<KeyEventItem> globalHotkeys { get; set; }
public List<CoreTypeItem> coreTypeItem { get; set; } public List<CoreTypeItem> coreTypeItem { get; set; }

View file

@ -73,8 +73,6 @@ namespace v2rayN.Mode
[Serializable] [Serializable]
public class ConstItem public class ConstItem
{ {
public string speedTestUrl { get; set; }
public string speedPingTestUrl { get; set; }
public string defIEProxyExceptions { get; set; } public string defIEProxyExceptions { get; set; }
} }
@ -117,4 +115,14 @@ namespace v2rayN.Mode
public List<string> proxyProcess { get; set; } public List<string> proxyProcess { get; set; }
} }
[Serializable]
public class SpeedTestItem
{
public int speedTestTimeout { get; set; }
public string speedTestUrl { get; set; }
public string speedPingTestUrl { get; set; }
}
} }

View file

@ -790,7 +790,7 @@ namespace v2rayN.Resx {
} }
/// <summary> /// <summary>
/// 查找类似 One-click test Latency and speed (Ctrl+E) 的本地化字符串。 /// 查找类似 One-click multi test Latency and speed (Ctrl+E) 的本地化字符串。
/// </summary> /// </summary>
public static string menuMixedTestServer { public static string menuMixedTestServer {
get { get {
@ -2689,6 +2689,24 @@ namespace v2rayN.Resx {
} }
} }
/// <summary>
/// 查找类似 SpeedTest Single Timeout Value 的本地化字符串。
/// </summary>
public static string TbSettingsSpeedTestTimeout {
get {
return ResourceManager.GetString("TbSettingsSpeedTestTimeout", resourceCulture);
}
}
/// <summary>
/// 查找类似 SpeedTest Url 的本地化字符串。
/// </summary>
public static string TbSettingsSpeedTestUrl {
get {
return ResourceManager.GetString("TbSettingsSpeedTestUrl", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Start on boot 的本地化字符串。 /// 查找类似 Start on boot 的本地化字符串。
/// </summary> /// </summary>

View file

@ -1022,7 +1022,7 @@
<value>RouteOnly</value> <value>RouteOnly</value>
</data> </data>
<data name="menuMixedTestServer" xml:space="preserve"> <data name="menuMixedTestServer" xml:space="preserve">
<value>One-click test Latency and speed (Ctrl+E)</value> <value>One-click multi test Latency and speed (Ctrl+E)</value>
</data> </data>
<data name="LvTestDelay" xml:space="preserve"> <data name="LvTestDelay" xml:space="preserve">
<value>Delay(ms)</value> <value>Delay(ms)</value>
@ -1120,4 +1120,10 @@
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve"> <data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
<value>Enable: If no route matches, the final proxy</value> <value>Enable: If no route matches, the final proxy</value>
</data> </data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>SpeedTest Single Timeout Value</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>SpeedTest Url</value>
</data>
</root> </root>

View file

@ -1022,7 +1022,7 @@
<value>RouteOnly</value> <value>RouteOnly</value>
</data> </data>
<data name="menuMixedTestServer" xml:space="preserve"> <data name="menuMixedTestServer" xml:space="preserve">
<value>一键测试延迟和速度 (Ctrl+E)</value> <value>一键多线程测试延迟和速度 (Ctrl+E)</value>
</data> </data>
<data name="LvTestDelay" xml:space="preserve"> <data name="LvTestDelay" xml:space="preserve">
<value>延迟(ms)</value> <value>延迟(ms)</value>
@ -1120,4 +1120,10 @@
<data name="TbSettingsTunModeBypassModeTip" xml:space="preserve"> <data name="TbSettingsTunModeBypassModeTip" xml:space="preserve">
<value>启用:路由无匹配则最终代理</value> <value>启用:路由无匹配则最终代理</value>
</data> </data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>测速单个超时值</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>测速文件地址</value>
</data>
</root> </root>

View file

@ -63,6 +63,8 @@ namespace v2rayN.ViewModels
[Reactive] public int autoUpdateSubInterval { get; set; } [Reactive] public int autoUpdateSubInterval { get; set; }
[Reactive] public int trayMenuServersLimit { get; set; } [Reactive] public int trayMenuServersLimit { get; set; }
[Reactive] public string currentFontFamily { get; set; } [Reactive] public string currentFontFamily { get; set; }
[Reactive] public int SpeedTestTimeout { get; set; }
[Reactive] public string SpeedTestUrl { get; set; }
#endregion #endregion
@ -153,6 +155,8 @@ namespace v2rayN.ViewModels
autoUpdateSubInterval = _config.autoUpdateSubInterval; autoUpdateSubInterval = _config.autoUpdateSubInterval;
trayMenuServersLimit = _config.trayMenuServersLimit; trayMenuServersLimit = _config.trayMenuServersLimit;
currentFontFamily = _config.uiItem.currentFontFamily; currentFontFamily = _config.uiItem.currentFontFamily;
SpeedTestTimeout = _config.speedTestItem.speedTestTimeout;
SpeedTestUrl = _config.speedTestItem.speedTestUrl;
#endregion #endregion
@ -327,6 +331,8 @@ namespace v2rayN.ViewModels
_config.uiItem.doubleClick2Activate = DoubleClick2Activate; _config.uiItem.doubleClick2Activate = DoubleClick2Activate;
_config.trayMenuServersLimit = trayMenuServersLimit; _config.trayMenuServersLimit = trayMenuServersLimit;
_config.uiItem.currentFontFamily = currentFontFamily; _config.uiItem.currentFontFamily = currentFontFamily;
_config.speedTestItem.speedTestTimeout = SpeedTestTimeout;
_config.speedTestItem.speedTestUrl = SpeedTestUrl;
//systemProxy //systemProxy
_config.systemProxyExceptions = systemProxyExceptions; _config.systemProxyExceptions = systemProxyExceptions;

View file

@ -478,6 +478,8 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
@ -660,6 +662,7 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
@ -675,6 +678,7 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
@ -690,6 +694,7 @@
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource SettingItemMargin}" Margin="{StaticResource SettingItemMargin}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" /> Style="{StaticResource DefTextBox}" />
<TextBlock <TextBlock
@ -714,6 +719,36 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}" Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}" /> Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}" />
<TextBlock
Grid.Row="16"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSpeedTestTimeout}" />
<ComboBox
x:Name="cmbSpeedTestTimeout"
Grid.Row="16"
Grid.Column="1"
Width="200"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="17"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSpeedTestUrl}" />
<ComboBox
x:Name="cmbSpeedTestUrl"
Grid.Row="17"
Grid.Column="1"
Width="300"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>

View file

@ -63,6 +63,15 @@ namespace v2rayN.Views
cmbCoreType6.Items.Add(it); cmbCoreType6.Items.Add(it);
}); });
for (int i = 2; i <= 6; i++)
{
cmbSpeedTestTimeout.Items.Add(i * 5);
}
Global.SpeedTestUrls.ForEach(it =>
{
cmbSpeedTestUrl.Items.Add(it);
});
//fill fonts //fill fonts
try try
{ {
@ -153,6 +162,8 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.autoUpdateSubInterval, v => v.txtautoUpdateSubInterval.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.autoUpdateSubInterval, v => v.txtautoUpdateSubInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.trayMenuServersLimit, v => v.txttrayMenuServersLimit.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.trayMenuServersLimit, v => v.txttrayMenuServersLimit.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.currentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.currentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);

View file

@ -13,6 +13,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Downloader" Version="3.0.3" />
<PackageReference Include="MaterialDesignThemes" Version="4.7.1" /> <PackageReference Include="MaterialDesignThemes" Version="4.7.1" />
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" /> <PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
@ -22,10 +23,10 @@
<PackageReference Include="sqlite-net-pcl" Version="1.8.116" /> <PackageReference Include="sqlite-net-pcl" Version="1.8.116" />
<PackageReference Include="TaskScheduler" Version="2.10.1" /> <PackageReference Include="TaskScheduler" Version="2.10.1" />
<PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.10" /> <PackageReference Include="ZXing.Net.Bindings.Windows.Compatibility" Version="0.16.10" />
<PackageReference Include="ReactiveUI.Fody" Version="18.4.1" /> <PackageReference Include="ReactiveUI.Fody" Version="18.4.20" />
<PackageReference Include="ReactiveUI.Validation" Version="3.0.22" /> <PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
<PackageReference Include="ReactiveUI.WPF" Version="18.4.1" /> <PackageReference Include="ReactiveUI.WPF" Version="18.4.20" />
<PackageReference Include="Splat.NLog" Version="14.6.1" /> <PackageReference Include="Splat.NLog" Version="14.6.8" />
<PackageReference Include="System.Reactive" Version="5.0.0" /> <PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup> </ItemGroup>