Compare commits

..

No commits in common. "1c04144573cd2e57df137cbf42f9b33d6626bc24" and "0032a3d27af7d91010233bed494105120f0cff5b" have entirely different histories.

16 changed files with 188 additions and 252 deletions

View file

@ -31,6 +31,15 @@ public sealed class AppHandler
}
}
public bool IsAdministrator
{
get
{
_isAdministrator ??= Utils.IsAdministrator();
return _isAdministrator.Value;
}
}
public string LinuxSudoPwd { get; set; }
#endregion Property

View file

@ -1,144 +0,0 @@
using System.Diagnostics;
using System.Text;
using CliWrap;
namespace ServiceLib.Handler;
public class CoreAdminHandler
{
private static readonly Lazy<CoreAdminHandler> _instance = new(() => new());
public static CoreAdminHandler Instance => _instance.Value;
private Config _config;
private Action<bool, string>? _updateFunc;
private const string _tag = "CoreAdminHandler";
private int _linuxSudoPid = -1;
public async Task Init(Config config, Action<bool, string> updateFunc)
{
if (_config != null)
{
return;
}
_config = config;
_updateFunc = updateFunc;
}
private void UpdateFunc(bool notify, string msg)
{
_updateFunc?.Invoke(notify, msg);
}
public async Task<Process?> RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath)
{
try
{
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
Process proc = new()
{
StartInfo = new()
{
FileName = shFilePath,
Arguments = "",
WorkingDirectory = Utils.GetBinConfigPath(),
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardInputEncoding = Encoding.UTF8,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8,
}
};
proc.OutputDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync();
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
await Task.Delay(100);
if (proc is null or { HasExited: true })
{
throw new Exception(ResUI.FailedToRunCore);
}
_linuxSudoPid = proc.Id;
return proc;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
UpdateFunc(false, ex.Message);
return null;
}
}
public async Task KillProcessAsLinuxSudo()
{
if (_linuxSudoPid < 0)
{
return;
}
try
{
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
var result = await Cli.Wrap(shFilePath)
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
.ExecuteAsync();
_linuxSudoPid = -1;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
UpdateFunc(false, ex.Message);
}
}
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
{
var shFilePath = Utils.GetBinConfigPath(fileName);
File.Delete(shFilePath);
var sb = new StringBuilder();
sb.AppendLine("#!/bin/sh");
if (Utils.IsAdministrator())
{
sb.AppendLine($"{cmdLine}");
}
else
{
sb.AppendLine($"sudo -S {cmdLine}");
}
await File.WriteAllTextAsync(shFilePath, sb.ToString());
await Utils.SetLinuxChmod(shFilePath);
return shFilePath;
}
}

View file

@ -13,7 +13,7 @@ public class CoreHandler
private Config _config;
private Process? _process;
private Process? _processPre;
private bool _linuxSudo = false;
private int _linuxSudoPid = -1;
private Action<bool, string>? _updateFunc;
private const string _tag = "CoreHandler";
@ -155,21 +155,21 @@ public class CoreHandler
{
try
{
if (_linuxSudo)
if (_linuxSudoPid > 0)
{
await CoreAdminHandler.Instance.KillProcessAsLinuxSudo();
_linuxSudo = false;
await KillProcessAsLinuxSudo();
_linuxSudoPid = -1;
}
if (_process != null)
{
await ProcUtils.ProcessKill(_process, Utils.IsWindows());
await ProcUtils.ProcessKill(_process, true);
_process = null;
}
if (_processPre != null)
{
await ProcUtils.ProcessKill(_processPre, Utils.IsWindows());
await ProcUtils.ProcessKill(_processPre, true);
_processPre = null;
}
}
@ -225,6 +225,13 @@ public class CoreHandler
_updateFunc?.Invoke(notify, msg);
}
private bool IsNeedSudo(ECoreType eCoreType)
{
return _config.TunModeItem.EnableTun
&& eCoreType == ECoreType.sing_box
&& Utils.IsNonWindows();
}
#endregion Private
#region Process
@ -238,16 +245,6 @@ public class CoreHandler
return null;
}
if (mayNeedSudo
&& _config.TunModeItem.EnableTun
&& coreInfo.CoreType == ECoreType.sing_box
&& Utils.IsNonWindows())
{
_linuxSudo = true;
await CoreAdminHandler.Instance.Init(_config, _updateFunc);
return await CoreAdminHandler.Instance.RunProcessAsLinuxSudo(fileName, coreInfo, configPath);
}
try
{
Process proc = new()
@ -266,25 +263,38 @@ public class CoreHandler
}
};
var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
if (isNeedSudo)
{
await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath);
}
if (displayLog)
{
proc.OutputDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
if (e.Data.IsNullOrEmpty())
return;
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
proc.ErrorDataReceived += (sender, e) =>
{
if (e.Data.IsNotEmpty())
{
if (e.Data.IsNullOrEmpty())
return;
UpdateFunc(false, e.Data + Environment.NewLine);
}
};
}
proc.Start();
if (isNeedSudo && AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
await proc.StandardInput.WriteLineAsync();
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
}
if (isNeedSudo)
_linuxSudoPid = proc.Id;
if (displayLog)
{
proc.BeginOutputReadLine();
@ -308,4 +318,82 @@ public class CoreHandler
}
#endregion Process
#region Linux
private async Task RunProcessAsLinuxSudo(Process proc, string fileName, CoreInfo coreInfo, string configPath)
{
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
proc.StartInfo.FileName = shFilePath;
proc.StartInfo.Arguments = "";
proc.StartInfo.WorkingDirectory = "";
if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
proc.StartInfo.RedirectStandardInput = true;
}
}
private async Task KillProcessAsLinuxSudo()
{
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
Process proc = new()
{
StartInfo = new()
{
FileName = shFilePath,
UseShellExecute = false,
CreateNoWindow = true,
StandardInputEncoding = Encoding.UTF8,
RedirectStandardInput = true
}
};
proc.Start();
if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
{
try
{
await proc.StandardInput.WriteLineAsync();
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
}
catch (Exception)
{
// ignored
}
}
var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await proc.WaitForExitAsync(timeout.Token);
await Task.Delay(1000);
}
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
{
//Shell scripts
var shFilePath = Utils.GetBinConfigPath(AppHandler.Instance.IsAdministrator ? "root_" + fileName : fileName);
File.Delete(shFilePath);
var sb = new StringBuilder();
sb.AppendLine("#!/bin/sh");
if (AppHandler.Instance.IsAdministrator)
{
sb.AppendLine($"{cmdLine}");
}
else
{
sb.AppendLine($"sudo -S {cmdLine}");
}
await File.WriteAllTextAsync(shFilePath, sb.ToString());
await Utils.SetLinuxChmod(shFilePath);
//Logging.SaveLog(shFilePath);
return shFilePath;
}
#endregion Linux
}

View file

@ -454,7 +454,7 @@ public class StatusBarViewModel : MyReactiveObject
{
if (Utils.IsWindows())
{
return Utils.IsAdministrator();
return AppHandler.Instance.IsAdministrator;
}
else if (Utils.IsLinux())
{

View file

@ -143,7 +143,7 @@ public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
}
else
{
if (Utils.IsAdministrator())
if (AppHandler.Instance.IsAdministrator)
{
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);

View file

@ -8,6 +8,7 @@ using DialogHostAvalonia;
using ReactiveUI;
using Splat;
using v2rayN.Desktop.Common;
using static QRCoder.PayloadGenerator;
namespace v2rayN.Desktop.Views;

View file

@ -1,9 +1,9 @@
<Application
x:Class="v2rayN.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>

View file

@ -1,14 +1,14 @@
<reactiveui:ReactiveWindow
x:Class="v2rayN.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:view="clr-namespace:v2rayN.Views"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:view="clr-namespace:v2rayN.Views"
Title="v2rayN"
Width="900"
Height="700"
@ -42,7 +42,8 @@
ClipToBounds="True"
Style="{StaticResource MaterialDesignToolBar}">
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuServers}">
<MenuItem Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
@ -110,7 +111,8 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuSubscription}">
<MenuItem Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuSubscription}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
@ -145,7 +147,8 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuSetting}">
<MenuItem Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuSetting}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
@ -211,9 +214,7 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem
x:Name="menuReload"
Padding="8,0"
<MenuItem x:Name="menuReload" Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuReload}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -228,9 +229,7 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem
Name="menuCheckUpdate"
Padding="8,0"
<MenuItem Name="menuCheckUpdate" Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuCheckUpdate}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -245,9 +244,7 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem
x:Name="menuHelp"
Padding="8,0"
<MenuItem x:Name="menuHelp" Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuHelp}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -262,9 +259,7 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem
x:Name="menuPromotion"
Padding="8,0"
<MenuItem x:Name="menuPromotion" Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuPromotion}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -279,9 +274,7 @@
</Menu>
<Separator />
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
<MenuItem
x:Name="menuClose"
Padding="8,0"
<MenuItem x:Name="menuClose" Padding="8,0"
AutomationProperties.Name="{x:Static resx:ResUI.menuClose}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">

View file

@ -132,7 +132,7 @@ public partial class MainWindow
}
});
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
if (!_config.GuiItem.EnableHWA)
{

View file

@ -40,9 +40,9 @@
Width="30"
Height="30"
Margin="{StaticResource MarginLeftRight4}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSubEdit}"
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
ToolTip="{x:Static resx:ResUI.menuSubEdit}">
ToolTip="{x:Static resx:ResUI.menuSubEdit}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSubEdit}">
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Edit" />
</Button>
<Button
@ -50,9 +50,9 @@
Width="30"
Height="30"
Margin="{StaticResource MarginLeftRight4}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSubAdd}"
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
ToolTip="{x:Static resx:ResUI.menuSubAdd}">
ToolTip="{x:Static resx:ResUI.menuSubAdd}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSubAdd}">
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Plus" />
</Button>
@ -61,9 +61,9 @@
Width="30"
Height="30"
Margin="{StaticResource MarginLeftRight8}"
AutomationProperties.Name="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}"
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
ToolTip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
ToolTip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}"
AutomationProperties.Name="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ArrowSplitVertical" />
</Button>
<TextBox
@ -73,8 +73,8 @@
VerticalContentAlignment="Center"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
materialDesign:TextFieldAssist.HasClearButton="True"
AutomationProperties.Name="{x:Static resx:ResUI.MsgServerTitle}"
Style="{StaticResource DefTextBox}" />
Style="{StaticResource DefTextBox}"
AutomationProperties.Name="{x:Static resx:ResUI.MsgServerTitle}" />
</WrapPanel>
<DataGrid
x:Name="lstProfiles"

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"

View file

@ -61,8 +61,7 @@
x:Name="togEnableTun"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Static resx:ResUI.TbEnableTunAs}" />
VerticalAlignment="Center" AutomationProperties.Name="{x:Static resx:ResUI.TbEnableTunAs}" />
</StackPanel>
<StackPanel
@ -75,9 +74,9 @@
Width="160"
Margin="{StaticResource MarginLeftRight8}"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemproxy}"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemproxy}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
@ -89,10 +88,10 @@
Width="160"
Margin="{StaticResource MarginLeftRight8}"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"/>
</StackPanel>
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
@ -110,9 +109,7 @@
ToolTipText="v2rayN">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu Style="{StaticResource DefContextMenu}">
<MenuItem
x:Name="menuSystemProxyClear"
Height="{StaticResource MenuItemHeight}"
<MenuItem x:Name="menuSystemProxyClear" Height="{StaticResource MenuItemHeight}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyClear}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -125,9 +122,7 @@
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem
x:Name="menuSystemProxySet"
Height="{StaticResource MenuItemHeight}"
<MenuItem x:Name="menuSystemProxySet" Height="{StaticResource MenuItemHeight}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxySet}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -140,9 +135,7 @@
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem
x:Name="menuSystemProxyNothing"
Height="{StaticResource MenuItemHeight}"
<MenuItem x:Name="menuSystemProxyNothing" Height="{StaticResource MenuItemHeight}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyNothing}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -155,9 +148,7 @@
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem
x:Name="menuSystemProxyPac"
Height="{StaticResource MenuItemHeight}"
<MenuItem x:Name="menuSystemProxyPac" Height="{StaticResource MenuItemHeight}"
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyPac}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
@ -171,9 +162,7 @@
</MenuItem.Header>
</MenuItem>
<Separator x:Name="sepRoutings" />
<MenuItem
x:Name="menuRoutings"
Height="Auto"
<MenuItem x:Name="menuRoutings" Height="Auto"
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}">
<MenuItem.Header>
<DockPanel>
@ -181,10 +170,10 @@
x:Name="cmbRoutings"
MaxWidth="300"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" />
Style="{StaticResource MaterialDesignFilledComboBox}"
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"/>
</DockPanel>
</MenuItem.Header>
</MenuItem>
@ -195,10 +184,10 @@
x:Name="cmbServers"
MaxWidth="300"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
DisplayMemberPath="Text"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" />
Style="{StaticResource MaterialDesignFilledComboBox}"
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"/>
</DockPanel>
</MenuItem.Header>
</MenuItem>

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow
x:Class="v2rayN.Views.SubEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSubSetting}"

View file

@ -1,11 +1,11 @@
<reactiveui:ReactiveWindow
x:Class="v2rayN.Views.SubSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSubSetting}"

View file

@ -1,10 +1,10 @@
<reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ThemeSettingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450"