Add system proxy for Linux

pull/5767/head
2dust 2024-09-28 10:41:30 +08:00
parent fde2a768cf
commit 1411643192
9 changed files with 169 additions and 35 deletions

View File

@ -0,0 +1,8 @@
namespace ServiceLib.Models
{
public class CmdItem
{
public string? Cmd { get; set; }
public string? Arguments { get; set; }
}
}

View File

@ -16,6 +16,7 @@
<PackageReference Include="WebDav.Client" Version="2.8.0" />
<PackageReference Include="YamlDotNet" Version="16.1.2" />
<PackageReference Include="QRCoder" Version="1.6.0" />
<PackageReference Include="CliWrap" Version="3.6.6" />
</ItemGroup>
<ItemGroup>

View File

@ -67,12 +67,15 @@ namespace ServiceLib.ViewModels
coreType = ECoreType.mihomo.ToString(),
remarks = ResUI.menuCheckUpdate,
});
_checkUpdateItem.Add(new CheckUpdateItem()
if (Utils.IsWindows())
{
isSelected = true,
coreType = ECoreType.sing_box.ToString(),
remarks = ResUI.menuCheckUpdate,
});
_checkUpdateItem.Add(new CheckUpdateItem()
{
isSelected = true,
coreType = ECoreType.sing_box.ToString(),
remarks = ResUI.menuCheckUpdate,
});
}
_checkUpdateItem.Add(new CheckUpdateItem()
{
isSelected = true,

View File

@ -295,7 +295,14 @@ namespace ServiceLib.ViewModels
});
OpenTheFileLocationCmd = ReactiveCommand.Create(() =>
{
Utils.ProcessStart("Explorer", $"/select,{Utils.GetConfigPath()}");
if (Utils.IsWindows())
{
Utils.ProcessStart("Explorer", $"/select,{Utils.GetConfigPath()}");
}
else if (Utils.IsLinux())
{
Utils.ProcessStart("nautilus", Utils.GetConfigPath());
}
});
ReloadCmd = ReactiveCommand.Create(() =>

View File

@ -0,0 +1,94 @@
using CliWrap;
using CliWrap.Buffered;
namespace v2rayN.Desktop.Common
{
public class ProxySettingLinux
{
public static async Task SetProxy(string host, int port)
{
var lstCmd = GetSetCmds(host, port);
await ExecCmd(lstCmd);
}
public static async Task UnsetProxy()
{
var lstCmd = GetUnsetCmds();
await ExecCmd(lstCmd);
}
private static async Task ExecCmd(List<CmdItem> lstCmd)
{
foreach (var cmd in lstCmd)
{
if (cmd is null || cmd.Cmd.IsNullOrEmpty() || cmd.Arguments.IsNullOrEmpty())
{ continue; }
await Task.Delay(10);
var result = await Cli.Wrap(cmd.Cmd)
.WithArguments(cmd.Arguments)
.ExecuteBufferedAsync();
if (result.ExitCode != 0)
{
//Logging.SaveLog($"Command failed {cmd.Cmd},{cmd.Arguments}");
Logging.SaveLog(result.ToString() ?? "");
}
}
}
private static List<CmdItem> GetSetCmds(string host, int port)
{
//TODO KDE //XDG_CURRENT_DESKTOP
List<string> lstType = ["http", "https", "socks", "ftp"];
List<CmdItem> lstCmd = [];
lstCmd.Add(new CmdItem()
{
Cmd = "gsettings",
Arguments = "set org.gnome.system.proxy mode manual"
});
foreach (string type in lstType)
{
lstCmd.AddRange(GetSetCmdByType(type, host, port));
}
return lstCmd;
}
private static List<CmdItem> GetSetCmdByType(string type, string host, int port)
{
List<CmdItem> lstCmd = [];
lstCmd.Add(new()
{
Cmd = "gsettings",
Arguments = $"set org.gnome.system.proxy.{type} host {host}",
});
lstCmd.Add(new()
{
Cmd = "gsettings",
Arguments = $"set org.gnome.system.proxy.{type} port {port}",
});
return lstCmd;
}
private static List<CmdItem> GetUnsetCmds()
{
//TODO KDE
List<CmdItem> lstCmd = [];
lstCmd.Add(new CmdItem()
{
Cmd = "gsettings",
Arguments = "set org.gnome.system.proxy mode none"
});
return lstCmd;
}
}
}

View File

@ -0,0 +1,13 @@
namespace v2rayN.Desktop.Common
{
public class ProxySettingOSX
{
public static async Task SetProxy(string host, int port)
{
}
public static async Task UnsetProxy()
{
}
}
}

View File

@ -1,4 +1,6 @@
namespace v2rayN.Desktop.Handler
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Handler
{
public static class SysProxyHandler
{
@ -14,22 +16,50 @@
try
{
int port = LazyConfig.Instance.GetLocalPort(EInboundProtocol.http);
int portSocks = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks);
int portPac = LazyConfig.Instance.GetLocalPort(EInboundProtocol.pac);
if (port <= 0)
{
return false;
}
if (type == ESysProxyType.ForcedChange)
{
var strProxy = $"{Global.Loopback}:{port}";
await SetProxy(strProxy);
if (Utils.IsWindows())
{
//TODO
}
else if (Utils.IsLinux())
{
await ProxySettingLinux.SetProxy(Global.Loopback, port);
}
else if (Utils.IsOSX())
{
await ProxySettingOSX.SetProxy(Global.Loopback, port);
}
}
else if (type == ESysProxyType.ForcedClear)
{
await UnsetProxy();
if (Utils.IsWindows())
{
//TODO
}
else if (Utils.IsLinux())
{
await ProxySettingLinux.UnsetProxy();
}
else if (Utils.IsOSX())
{
await ProxySettingOSX.UnsetProxy();
}
}
else if (type == ESysProxyType.Unchanged)
else if (type == ESysProxyType.Pac)
{
}
//if (type != ESysProxyType.Pac)
//{
// PacHandler.Stop();
//}
}
catch (Exception ex)
{
@ -37,25 +67,5 @@
}
return true;
}
private static async Task SetProxy(string? strProxy)
{
await Task.Run(() =>
{
var httpProxy = strProxy is null ? null : $"{Global.HttpProtocol}{strProxy}";
var socksProxy = strProxy is null ? null : $"{Global.SocksProtocol}{strProxy}";
var noProxy = $"localhost,127.0.0.0/8,::1";
Environment.SetEnvironmentVariable("http_proxy", httpProxy, EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("https_proxy", httpProxy, EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("all_proxy", socksProxy, EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("no_proxy", noProxy, EnvironmentVariableTarget.User);
});
}
private static async Task UnsetProxy()
{
await SetProxy(null);
}
}
}

View File

@ -165,7 +165,6 @@
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyPac}" />
</ComboBox>
<ComboBox

View File

@ -11,6 +11,7 @@ using Splat;
using System.ComponentModel;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
using v2rayN.Desktop.Handler;
namespace v2rayN.Desktop.Views
{
@ -124,8 +125,6 @@ namespace v2rayN.Desktop.Views
menuRebootAsAdmin.IsVisible = false;
menuSettingsSetUWP.IsVisible = false;
menuGlobalHotkeySetting.IsVisible = false;
menuOpenTheFileLocation.IsVisible = false;
cmbSystemProxy.IsVisible = false;
if (_config.tunModeItem.enableTun)
{
ViewModel.EnableTun = true;
@ -255,7 +254,7 @@ namespace v2rayN.Desktop.Views
case EViewAction.UpdateSysProxy:
if (obj is null) return false;
// await SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
await SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
break;
case EViewAction.AddServerViaClipboard: