mirror of https://github.com/2dust/v2rayN
Refactor code to decouple view and viewmodel
parent
9e9808e489
commit
9aa5c0d135
|
@ -11,24 +11,24 @@ namespace v2rayN.Common
|
|||
{
|
||||
if (type == 1)
|
||||
{
|
||||
Utils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||
Utils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||
}
|
||||
if (type == 2)
|
||||
{
|
||||
Utils.RegWriteValue(_regPath, "ProxyEnable", 1);
|
||||
Utils.RegWriteValue(_regPath, "ProxyServer", strProxy ?? string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "ProxyOverride", exceptions ?? string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 1);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", strProxy ?? string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", exceptions ?? string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||
}
|
||||
else if (type == 4)
|
||||
{
|
||||
Utils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||
Utils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||
Utils.RegWriteValue(_regPath, "AutoConfigURL", strProxy ?? string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", strProxy ?? string.Empty);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Collections.Specialized;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace v2rayN
|
||||
{
|
||||
|
@ -345,14 +337,6 @@ namespace v2rayN
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static ImageSource IconToImageSource(Icon icon)
|
||||
{
|
||||
return Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// idn to idc
|
||||
/// </summary>
|
||||
|
@ -420,11 +404,7 @@ namespace v2rayN
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文本
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static bool IsNullOrEmpty(string? text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
|
@ -631,43 +611,6 @@ namespace v2rayN
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取剪贴板数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string? GetClipboardData()
|
||||
{
|
||||
string? strData = string.Empty;
|
||||
try
|
||||
{
|
||||
IDataObject data = Clipboard.GetDataObject();
|
||||
if (data.GetDataPresent(DataFormats.UnicodeText))
|
||||
{
|
||||
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
|
||||
}
|
||||
return strData;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
return strData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝至剪贴板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static void SetClipboardData(string strData)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(strData);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取得GUID
|
||||
|
@ -752,23 +695,6 @@ namespace v2rayN
|
|||
}
|
||||
}
|
||||
|
||||
public static void SetDarkBorder(System.Windows.Window window, bool dark)
|
||||
{
|
||||
// Make sure the handle is created before the window is shown
|
||||
IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).EnsureHandle();
|
||||
int attribute = dark ? 1 : 0;
|
||||
uint attributeSize = (uint)Marshal.SizeOf(attribute);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref attribute, attributeSize);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
||||
}
|
||||
|
||||
public static bool IsLightTheme()
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
|
||||
var value = key?.GetValue("AppsUseLightTheme");
|
||||
return value is int i && i > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统hosts
|
||||
/// </summary>
|
||||
|
@ -958,12 +884,13 @@ namespace v2rayN
|
|||
try
|
||||
{
|
||||
var autoRunName = $"{AutoRunName}_{GetMD5(StartupPath())}";
|
||||
WindowsUtils.
|
||||
|
||||
//delete first
|
||||
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
||||
//delete first
|
||||
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
||||
if (IsAdministrator())
|
||||
{
|
||||
AutoStart(autoRunName, "", "");
|
||||
WindowsUtils.AutoStart(autoRunName, "", "");
|
||||
}
|
||||
|
||||
if (run)
|
||||
|
@ -971,11 +898,11 @@ namespace v2rayN
|
|||
string exePath = GetExePath();
|
||||
if (IsAdministrator())
|
||||
{
|
||||
AutoStart(autoRunName, exePath, "");
|
||||
WindowsUtils.AutoStart(autoRunName, exePath, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
RegWriteValue(AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
||||
WindowsUtils.RegWriteValue(AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -985,146 +912,8 @@ namespace v2rayN
|
|||
}
|
||||
}
|
||||
|
||||
public static string? RegReadValue(string path, string name, string def)
|
||||
{
|
||||
RegistryKey? regKey = null;
|
||||
try
|
||||
{
|
||||
regKey = Registry.CurrentUser.OpenSubKey(path, false);
|
||||
string? value = regKey?.GetValue(name) as string;
|
||||
if (IsNullOrEmpty(value))
|
||||
{
|
||||
return def;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
regKey?.Close();
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
public static void RegWriteValue(string path, string name, object value)
|
||||
{
|
||||
RegistryKey? regKey = null;
|
||||
try
|
||||
{
|
||||
regKey = Registry.CurrentUser.CreateSubKey(path);
|
||||
if (IsNullOrEmpty(value.ToString()))
|
||||
{
|
||||
regKey?.DeleteValue(name, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
regKey?.SetValue(name, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
regKey?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto Start via TaskService
|
||||
/// </summary>
|
||||
/// <param name="taskName"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static void AutoStart(string taskName, string fileName, string description)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(taskName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string TaskName = taskName;
|
||||
var logonUser = WindowsIdentity.GetCurrent().Name;
|
||||
string taskDescription = description;
|
||||
string deamonFileName = fileName;
|
||||
|
||||
using var taskService = new TaskService();
|
||||
var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));
|
||||
foreach (var t in tasks)
|
||||
{
|
||||
taskService.RootFolder.DeleteTask(t.Name);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var task = taskService.NewTask();
|
||||
task.RegistrationInfo.Description = taskDescription;
|
||||
task.Settings.DisallowStartIfOnBatteries = false;
|
||||
task.Settings.StopIfGoingOnBatteries = false;
|
||||
task.Settings.RunOnlyIfIdle = false;
|
||||
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
||||
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
||||
task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
||||
task.Principal.RunLevel = TaskRunLevel.Highest;
|
||||
task.Actions.Add(new ExecAction(deamonFileName.AppendQuotes(), null, Path.GetDirectoryName(deamonFileName)));
|
||||
|
||||
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
|
||||
}
|
||||
|
||||
public static void RemoveTunDevice()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
|
||||
var guid = new Guid(sum);
|
||||
string pnputilPath = @"C:\Windows\System32\pnputil.exe";
|
||||
string arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
|
||||
|
||||
// Try to remove the device
|
||||
Process proc = new()
|
||||
{
|
||||
StartInfo = new()
|
||||
{
|
||||
FileName = pnputilPath,
|
||||
Arguments = arg,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
proc.Start();
|
||||
var output = proc.StandardOutput.ReadToEnd();
|
||||
proc.WaitForExit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion 开机自动启动等
|
||||
|
||||
#region Windows API
|
||||
|
||||
[Flags]
|
||||
public enum DWMWINDOWATTRIBUTE : uint
|
||||
{
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
||||
}
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
||||
|
||||
#endregion Windows API
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace v2rayN
|
||||
{
|
||||
internal static class WindowsUtils
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取剪贴板数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string? GetClipboardData()
|
||||
{
|
||||
string? strData = string.Empty;
|
||||
try
|
||||
{
|
||||
IDataObject data = Clipboard.GetDataObject();
|
||||
if (data.GetDataPresent(DataFormats.UnicodeText))
|
||||
{
|
||||
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
|
||||
}
|
||||
return strData;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
return strData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝至剪贴板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static void SetClipboardData(string strData)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(strData);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Auto Start via TaskService
|
||||
/// </summary>
|
||||
/// <param name="taskName"></param>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static void AutoStart(string taskName, string fileName, string description)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(taskName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string TaskName = taskName;
|
||||
var logonUser = WindowsIdentity.GetCurrent().Name;
|
||||
string taskDescription = description;
|
||||
string deamonFileName = fileName;
|
||||
|
||||
using var taskService = new TaskService();
|
||||
var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));
|
||||
foreach (var t in tasks)
|
||||
{
|
||||
taskService.RootFolder.DeleteTask(t.Name);
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var task = taskService.NewTask();
|
||||
task.RegistrationInfo.Description = taskDescription;
|
||||
task.Settings.DisallowStartIfOnBatteries = false;
|
||||
task.Settings.StopIfGoingOnBatteries = false;
|
||||
task.Settings.RunOnlyIfIdle = false;
|
||||
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
||||
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
||||
task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
||||
task.Principal.RunLevel = TaskRunLevel.Highest;
|
||||
task.Actions.Add(new ExecAction(deamonFileName.AppendQuotes(), null, Path.GetDirectoryName(deamonFileName)));
|
||||
|
||||
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
|
||||
}
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
||||
|
||||
public static ImageSource IconToImageSource(Icon icon)
|
||||
{
|
||||
return Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
public static bool IsLightTheme()
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
|
||||
var value = key?.GetValue("AppsUseLightTheme");
|
||||
return value is int i && i > 0;
|
||||
}
|
||||
|
||||
public static string? RegReadValue(string path, string name, string def)
|
||||
{
|
||||
RegistryKey? regKey = null;
|
||||
try
|
||||
{
|
||||
regKey = Registry.CurrentUser.OpenSubKey(path, false);
|
||||
string? value = regKey?.GetValue(name) as string;
|
||||
if (Utils.IsNullOrEmpty(value))
|
||||
{
|
||||
return def;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
regKey?.Close();
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
public static void RegWriteValue(string path, string name, object value)
|
||||
{
|
||||
RegistryKey? regKey = null;
|
||||
try
|
||||
{
|
||||
regKey = Registry.CurrentUser.CreateSubKey(path);
|
||||
if (Utils.IsNullOrEmpty(value.ToString()))
|
||||
{
|
||||
regKey?.DeleteValue(name, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
regKey?.SetValue(name, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
regKey?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveTunDevice()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
|
||||
var guid = new Guid(sum);
|
||||
string pnputilPath = @"C:\Windows\System32\pnputil.exe";
|
||||
string arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
|
||||
|
||||
// Try to remove the device
|
||||
Process proc = new()
|
||||
{
|
||||
StartInfo = new()
|
||||
{
|
||||
FileName = pnputilPath,
|
||||
Arguments = arg,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
proc.Start();
|
||||
var output = proc.StandardOutput.ReadToEnd();
|
||||
proc.WaitForExit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetDarkBorder(System.Windows.Window window, bool dark)
|
||||
{
|
||||
// Make sure the handle is created before the window is shown
|
||||
IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).EnsureHandle();
|
||||
int attribute = dark ? 1 : 0;
|
||||
uint attributeSize = (uint)Marshal.SizeOf(attribute);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref attribute, attributeSize);
|
||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
||||
}
|
||||
|
||||
#region Windows API
|
||||
|
||||
[Flags]
|
||||
public enum DWMWINDOWATTRIBUTE : uint
|
||||
{
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
||||
}
|
||||
|
||||
#endregion Windows API
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@
|
|||
ShareSub,
|
||||
ShareServer,
|
||||
ShowHideWindow,
|
||||
ScanScreenTask,
|
||||
Shutdown,
|
||||
SubEditWindow,
|
||||
RoutingRuleSettingWindow,
|
||||
RoutingRuleDetailsWindow,
|
||||
|
@ -24,10 +26,10 @@
|
|||
DispatcherRefreshConnections,
|
||||
DispatcherRefreshProxyGroups,
|
||||
DispatcherProxiesDelayTest,
|
||||
|
||||
DispatcherStatistics,
|
||||
DispatcherServerAvailability,
|
||||
DispatcherReload,
|
||||
DispatcherRefreshServersBiz,
|
||||
DispatcherRefreshIcon,
|
||||
}
|
||||
}
|
|
@ -46,11 +46,11 @@ namespace v2rayN.Handler
|
|||
ShowMsg(false, msg);
|
||||
ShowMsg(true, $"{node.GetSummary()}");
|
||||
CoreStop();
|
||||
if (_config.tunModeItem.enableTun)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
Utils.RemoveTunDevice();
|
||||
}
|
||||
//if (_config.tunModeItem.enableTun)
|
||||
//{
|
||||
// Thread.Sleep(1000);
|
||||
// WindowsUtils.RemoveTunDevice();
|
||||
//}
|
||||
|
||||
CoreStart(node);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace v2rayN.Handler
|
|||
if (_config.globalHotkeys == null) return;
|
||||
foreach (var item in _config.globalHotkeys)
|
||||
{
|
||||
if (item.KeyCode != null && item.KeyCode != Key.None)
|
||||
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
||||
{
|
||||
int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
|
||||
KeyModifiers modifiers = KeyModifiers.None;
|
||||
|
|
|
@ -156,71 +156,7 @@ namespace v2rayN.Handler
|
|||
}
|
||||
}
|
||||
|
||||
public void UpdateTask(Config config, Action<bool, string> update)
|
||||
{
|
||||
Task.Run(() => UpdateTaskRunSubscription(config, update));
|
||||
Task.Run(() => UpdateTaskRunGeo(config, update));
|
||||
}
|
||||
|
||||
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> update)
|
||||
{
|
||||
await Task.Delay(60000);
|
||||
Logging.SaveLog("UpdateTaskRunSubscription");
|
||||
|
||||
var updateHandle = new UpdateHandle();
|
||||
while (true)
|
||||
{
|
||||
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||
var lstSubs = LazyConfig.Instance.SubItems()
|
||||
.Where(t => t.autoUpdateInterval > 0)
|
||||
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60)
|
||||
.ToList();
|
||||
|
||||
foreach (var item in lstSubs)
|
||||
{
|
||||
updateHandle.UpdateSubscriptionProcess(config, item.id, true, (bool success, string msg) =>
|
||||
{
|
||||
update(success, msg);
|
||||
if (success)
|
||||
Logging.SaveLog("subscription" + msg);
|
||||
});
|
||||
item.updateTime = updateTime;
|
||||
ConfigHandler.AddSubItem(config, item);
|
||||
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
await Task.Delay(60000);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateTaskRunGeo(Config config, Action<bool, string> update)
|
||||
{
|
||||
var autoUpdateGeoTime = DateTime.Now;
|
||||
|
||||
await Task.Delay(1000 * 120);
|
||||
Logging.SaveLog("UpdateTaskRunGeo");
|
||||
|
||||
var updateHandle = new UpdateHandle();
|
||||
while (true)
|
||||
{
|
||||
var dtNow = DateTime.Now;
|
||||
if (config.guiItem.autoUpdateInterval > 0)
|
||||
{
|
||||
if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)
|
||||
{
|
||||
updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>
|
||||
{
|
||||
update(false, msg);
|
||||
});
|
||||
autoUpdateGeoTime = dtNow;
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1000 * 3600);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterGlobalHotkey(Config config, Action<EGlobalHotkey> handler, Action<bool, string> update)
|
||||
public void RegisterGlobalHotkey(Config config, Action<EGlobalHotkey> handler, Action<bool, string>? update)
|
||||
{
|
||||
HotkeyHandler.Instance.UpdateViewEvent += update;
|
||||
HotkeyHandler.Instance.HotkeyTriggerEvent += handler;
|
||||
|
@ -240,7 +176,7 @@ namespace v2rayN.Handler
|
|||
{
|
||||
if (wParam == IntPtr.Zero && Marshal.PtrToStringUni(lParam) == "ImmersiveColorSet")
|
||||
{
|
||||
update(!Utils.IsLightTheme());
|
||||
update(!WindowsUtils.IsLightTheme());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Windows.Input;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Enums;
|
||||
|
||||
namespace v2rayN.Models
|
||||
{
|
||||
|
@ -152,7 +151,7 @@ namespace v2rayN.Models
|
|||
|
||||
public bool Shift { get; set; }
|
||||
|
||||
public Key? KeyCode { get; set; }
|
||||
public int? KeyCode { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
|
|
@ -3,13 +3,10 @@ using ReactiveUI;
|
|||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using v2rayN.Base;
|
||||
using v2rayN.Enums;
|
||||
using v2rayN.Handler;
|
||||
|
@ -95,12 +92,6 @@ namespace v2rayN.ViewModels
|
|||
|
||||
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
|
||||
|
||||
[Reactive]
|
||||
public Icon NotifyIcon { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public ImageSource AppIcon { get; set; }
|
||||
|
||||
#endregion Menu
|
||||
|
||||
#region System Proxy
|
||||
|
@ -259,9 +250,9 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
AddServerViaClipboard();
|
||||
});
|
||||
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(() =>
|
||||
AddServerViaScanCmd = ReactiveCommand.Create(() =>
|
||||
{
|
||||
return ScanScreenTaskAsync();
|
||||
_updateView?.Invoke(EViewAction.ScanScreenTask, null);
|
||||
});
|
||||
|
||||
//Subscription
|
||||
|
@ -390,9 +381,7 @@ namespace v2rayN.ViewModels
|
|||
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
|
||||
}
|
||||
|
||||
MainFormHandler.Instance.UpdateTask(_config, UpdateTaskHandler);
|
||||
MainFormHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, UpdateTaskHandler);
|
||||
|
||||
RegUpdateTask(_config, UpdateTaskHandler);
|
||||
RefreshRoutingsMenu();
|
||||
//RefreshServers();
|
||||
|
||||
|
@ -463,32 +452,6 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private void OnHotkeyHandler(EGlobalHotkey e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case EGlobalHotkey.ShowForm:
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, null);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyClear:
|
||||
SetListenerType(ESysProxyType.ForcedClear);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxySet:
|
||||
SetListenerType(ESysProxyType.ForcedChange);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyUnchanged:
|
||||
SetListenerType(ESysProxyType.Unchanged);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyPac:
|
||||
SetListenerType(ESysProxyType.Pac);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void MyAppExit(bool blWindowsShutDown)
|
||||
{
|
||||
try
|
||||
|
@ -517,7 +480,7 @@ namespace v2rayN.ViewModels
|
|||
catch { }
|
||||
finally
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
_updateView?.Invoke(EViewAction.Shutdown, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,7 +576,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
public void AddServerViaClipboard()
|
||||
{
|
||||
var clipboardData = Utils.GetClipboardData();
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
int ret = ConfigHandler.AddBatchServers(_config, clipboardData!, _config.subIndexId, false);
|
||||
if (ret > 0)
|
||||
{
|
||||
|
@ -623,18 +586,8 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public async Task ScanScreenTaskAsync()
|
||||
public void ScanScreenTaskAsync(string result)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, false);
|
||||
|
||||
var dpiXY = QRCodeHelper.GetDpiXY(Application.Current.MainWindow);
|
||||
string result = await Task.Run(() =>
|
||||
{
|
||||
return QRCodeHelper.ScanScreen(dpiXY.Item1, dpiXY.Item2);
|
||||
});
|
||||
|
||||
_updateView?.Invoke(EViewAction.ShowHideWindow, true);
|
||||
|
||||
if (Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.NoValidQRcodeFound);
|
||||
|
@ -869,6 +822,12 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (_config.tunModeItem.enableTun)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
WindowsUtils.RemoveTunDevice();
|
||||
}
|
||||
|
||||
var node = ConfigHandler.GetDefaultServer(_config);
|
||||
_coreHandler.LoadCore(node);
|
||||
});
|
||||
|
@ -914,8 +873,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
if (blChange)
|
||||
{
|
||||
NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);
|
||||
AppIcon = MainFormHandler.Instance.GetAppIcon(_config);
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -966,8 +924,7 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
_noticeHandler?.SendMessage(ResUI.TipChangeRouting, true);
|
||||
Reload();
|
||||
NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);
|
||||
AppIcon = MainFormHandler.Instance.GetAppIcon(_config);
|
||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1054,5 +1011,73 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
|
||||
#endregion UI
|
||||
|
||||
#region UpdateTask
|
||||
|
||||
private void RegUpdateTask(Config config, Action<bool, string> update)
|
||||
{
|
||||
Task.Run(() => UpdateTaskRunSubscription(config, update));
|
||||
Task.Run(() => UpdateTaskRunGeo(config, update));
|
||||
}
|
||||
|
||||
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> update)
|
||||
{
|
||||
await Task.Delay(60000);
|
||||
Logging.SaveLog("UpdateTaskRunSubscription");
|
||||
|
||||
var updateHandle = new UpdateHandle();
|
||||
while (true)
|
||||
{
|
||||
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||
var lstSubs = LazyConfig.Instance.SubItems()
|
||||
.Where(t => t.autoUpdateInterval > 0)
|
||||
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60)
|
||||
.ToList();
|
||||
|
||||
foreach (var item in lstSubs)
|
||||
{
|
||||
updateHandle.UpdateSubscriptionProcess(config, item.id, true, (bool success, string msg) =>
|
||||
{
|
||||
update(success, msg);
|
||||
if (success)
|
||||
Logging.SaveLog("subscription" + msg);
|
||||
});
|
||||
item.updateTime = updateTime;
|
||||
ConfigHandler.AddSubItem(config, item);
|
||||
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
await Task.Delay(60000);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateTaskRunGeo(Config config, Action<bool, string> update)
|
||||
{
|
||||
var autoUpdateGeoTime = DateTime.Now;
|
||||
|
||||
await Task.Delay(1000 * 120);
|
||||
Logging.SaveLog("UpdateTaskRunGeo");
|
||||
|
||||
var updateHandle = new UpdateHandle();
|
||||
while (true)
|
||||
{
|
||||
var dtNow = DateTime.Now;
|
||||
if (config.guiItem.autoUpdateInterval > 0)
|
||||
{
|
||||
if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)
|
||||
{
|
||||
updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>
|
||||
{
|
||||
update(false, msg);
|
||||
});
|
||||
autoUpdateGeoTime = dtNow;
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1000 * 3600);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion UpdateTask
|
||||
}
|
||||
}
|
|
@ -739,7 +739,7 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
Utils.SetClipboardData(sb.ToString());
|
||||
WindowsUtils.SetClipboardData(sb.ToString());
|
||||
_noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace v2rayN.ViewModels
|
|||
}
|
||||
if (lst.Count > 0)
|
||||
{
|
||||
Utils.SetClipboardData(JsonUtils.Serialize(lst));
|
||||
WindowsUtils.SetClipboardData(JsonUtils.Serialize(lst));
|
||||
//_noticeHandler?.Enqueue(ResUI.OperationSuccess"));
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
private void ImportRulesFromClipboard()
|
||||
{
|
||||
var clipboardData = Utils.GetClipboardData();
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
if (AddBatchRoutingRules(SelectedRouting, clipboardData) == 0)
|
||||
{
|
||||
RefreshRulesItems();
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace v2rayN.ViewModels
|
|||
{
|
||||
if (FollowSystemTheme)
|
||||
{
|
||||
ModifyTheme(!Utils.IsLightTheme());
|
||||
ModifyTheme(!WindowsUtils.IsLightTheme());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ namespace v2rayN.ViewModels
|
|||
ConfigHandler.SaveConfig(_config);
|
||||
if (FollowSystemTheme)
|
||||
{
|
||||
ModifyTheme(!Utils.IsLightTheme());
|
||||
ModifyTheme(!WindowsUtils.IsLightTheme());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -173,8 +173,7 @@ namespace v2rayN.ViewModels
|
|||
|
||||
theme.SetBaseTheme(isDarkTheme ? BaseTheme.Dark : BaseTheme.Light);
|
||||
_paletteHelper.SetTheme(theme);
|
||||
|
||||
Utils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
|
||||
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
|
||||
}
|
||||
|
||||
public void ChangePrimaryColor(System.Windows.Media.Color color)
|
||||
|
|
|
@ -38,8 +38,7 @@ namespace v2rayN.Views
|
|||
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
|
||||
});
|
||||
|
||||
Utils.SetDarkBorder(this, LazyConfig.Instance.GetConfig().uiItem.followSystemTheme ? !Utils.IsLightTheme() : LazyConfig.Instance.GetConfig().uiItem.colorModeDark);
|
||||
WindowsUtils.SetDarkBorder(this, LazyConfig.Instance.GetConfig().uiItem.followSystemTheme ? !WindowsUtils.IsLightTheme() : LazyConfig.Instance.GetConfig().uiItem.colorModeDark);
|
||||
}
|
||||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace v2rayN.Views
|
|||
|
||||
HotkeyHandler.Instance.IsPause = true;
|
||||
this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false;
|
||||
Utils.SetDarkBorder(this, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
||||
WindowsUtils.SetDarkBorder(this, _config.uiItem.followSystemTheme ? !WindowsUtils.IsLightTheme() : _config.uiItem.colorModeDark);
|
||||
InitData();
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ namespace v2rayN.Views
|
|||
e.Handled = true;
|
||||
var _ModifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift,
|
||||
Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin};
|
||||
_TextBoxKeyEventItem[sender].KeyCode = e.Key == Key.System ? (_ModifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (_ModifierKeys.Contains(e.Key) ? Key.None : e.Key);
|
||||
_TextBoxKeyEventItem[sender].KeyCode = (int)(e.Key == Key.System ? (_ModifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (_ModifierKeys.Contains(e.Key) ? Key.None : e.Key));
|
||||
_TextBoxKeyEventItem[sender].Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt;
|
||||
_TextBoxKeyEventItem[sender].Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
|
||||
_TextBoxKeyEventItem[sender].Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
|
||||
|
@ -78,8 +78,8 @@ namespace v2rayN.Views
|
|||
if (item.Control) res.Append($"{ModifierKeys.Control}+");
|
||||
if (item.Shift) res.Append($"{ModifierKeys.Shift}+");
|
||||
if (item.Alt) res.Append($"{ModifierKeys.Alt}+");
|
||||
if (item.KeyCode != null && item.KeyCode != Key.None)
|
||||
res.Append($"{item.KeyCode}");
|
||||
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
||||
res.Append($"{(Key)item.KeyCode}");
|
||||
|
||||
return res.ToString();
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ namespace v2rayN.Views
|
|||
{
|
||||
foreach (var item in _TextBoxKeyEventItem)
|
||||
{
|
||||
if (item.Value.KeyCode != null && item.Value.KeyCode != Key.None)
|
||||
if (item.Value.KeyCode != null && (Key)item.Value.KeyCode != Key.None)
|
||||
{
|
||||
(item.Key as TextBox)!.Text = KeyEventItemToString(item.Value);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace v2rayN.Views
|
|||
_TextBoxKeyEventItem[k].Alt = false;
|
||||
_TextBoxKeyEventItem[k].Control = false;
|
||||
_TextBoxKeyEventItem[k].Shift = false;
|
||||
_TextBoxKeyEventItem[k].KeyCode = Key.None;
|
||||
_TextBoxKeyEventItem[k].KeyCode = (int)Key.None;
|
||||
}
|
||||
BindingData();
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace v2rayN.Views
|
|||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
||||
|
||||
MainFormHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
//servers
|
||||
|
@ -106,10 +108,8 @@ namespace v2rayN.Views
|
|||
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.NotifyIcon, v => v.tbNotify.Icon).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
|
||||
this.OneWayBind(ViewModel, vm => vm.AppIcon, v => v.Icon).DisposeWith(disposables);
|
||||
|
||||
//status bar
|
||||
this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);
|
||||
|
@ -183,6 +183,8 @@ namespace v2rayN.Views
|
|||
AddHelpMenuItem();
|
||||
}
|
||||
|
||||
#region Event
|
||||
|
||||
private bool UpdateViewHandler(EViewAction action, object? obj)
|
||||
{
|
||||
switch (action)
|
||||
|
@ -246,12 +248,52 @@ namespace v2rayN.Views
|
|||
ViewModel?.RefreshServersBiz();
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.DispatcherRefreshIcon:
|
||||
Application.Current?.Dispatcher.Invoke((() =>
|
||||
{
|
||||
tbNotify.Icon = MainFormHandler.Instance.GetNotifyIcon(_config);
|
||||
this.Icon = MainFormHandler.Instance.GetAppIcon(_config);
|
||||
}), DispatcherPriority.Normal);
|
||||
break;
|
||||
|
||||
case EViewAction.Shutdown:
|
||||
Application.Current.Shutdown();
|
||||
break;
|
||||
|
||||
case EViewAction ScanScreenTask:
|
||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Event
|
||||
private void OnHotkeyHandler(EGlobalHotkey e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case EGlobalHotkey.ShowForm:
|
||||
ShowHideWindow(null);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyClear:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedClear);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxySet:
|
||||
ViewModel?.SetListenerType(ESysProxyType.ForcedChange);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyUnchanged:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Unchanged);
|
||||
break;
|
||||
|
||||
case EGlobalHotkey.SystemProxyPac:
|
||||
ViewModel?.SetListenerType(ESysProxyType.Pac);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void MainWindow_Closing(object? sender, CancelEventArgs e)
|
||||
{
|
||||
|
@ -286,7 +328,7 @@ namespace v2rayN.Views
|
|||
break;
|
||||
|
||||
case Key.S:
|
||||
ViewModel?.ScanScreenTaskAsync().ContinueWith(_ => { });
|
||||
ScanScreenTaskAsync().ContinueWith(_ => { });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -320,6 +362,21 @@ namespace v2rayN.Views
|
|||
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
||||
}
|
||||
|
||||
public async Task ScanScreenTaskAsync()
|
||||
{
|
||||
ShowHideWindow(false);
|
||||
|
||||
var dpiXY = QRCodeHelper.GetDpiXY(Application.Current.MainWindow);
|
||||
string result = await Task.Run(() =>
|
||||
{
|
||||
return QRCodeHelper.ScanScreen(dpiXY.Item1, dpiXY.Item2);
|
||||
});
|
||||
|
||||
ShowHideWindow(true);
|
||||
|
||||
ViewModel?.ScanScreenTaskAsync(result);
|
||||
}
|
||||
|
||||
#endregion Event
|
||||
|
||||
#region UI
|
||||
|
|
|
@ -99,13 +99,13 @@ namespace v2rayN.Views
|
|||
private void menuMsgViewCopy_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
var data = txtMsg.SelectedText.TrimEx();
|
||||
Utils.SetClipboardData(data);
|
||||
WindowsUtils.SetClipboardData(data);
|
||||
}
|
||||
|
||||
private void menuMsgViewCopyAll_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
var data = txtMsg.Text;
|
||||
Utils.SetClipboardData(data);
|
||||
WindowsUtils.SetClipboardData(data);
|
||||
}
|
||||
|
||||
private void menuMsgViewClear_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
|
|
Loading…
Reference in New Issue