diff --git a/v2rayN/v2rayN/Common/ProxySetting.cs b/v2rayN/v2rayN/Common/ProxySetting.cs
index cab0763317..1b102f5c6a 100644
--- a/v2rayN/v2rayN/Common/ProxySetting.cs
+++ b/v2rayN/v2rayN/Common/ProxySetting.cs
@@ -11,24 +11,24 @@ private static bool SetProxyFallback(string? strProxy, string? exceptions, int t
{
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;
}
diff --git a/v2rayN/v2rayN/Common/Utils.cs b/v2rayN/v2rayN/Common/Utils.cs
index 39f2f9a84b..77169165c8 100644
--- a/v2rayN/v2rayN/Common/Utils.cs
+++ b/v2rayN/v2rayN/Common/Utils.cs
@@ -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 @@ public static string GetMD5(string str)
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());
- }
-
///
/// idn to idc
///
@@ -420,11 +404,7 @@ public static bool IsNumeric(string oText)
}
}
- ///
- /// 文本
- ///
- ///
- ///
+
public static bool IsNullOrEmpty(string? text)
{
if (string.IsNullOrWhiteSpace(text))
@@ -631,43 +611,6 @@ public static string GetVersion(bool blFull = true)
}
}
- ///
- /// 获取剪贴板数
- ///
- ///
- 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;
- }
-
- ///
- /// 拷贝至剪贴板
- ///
- ///
- public static void SetClipboardData(string strData)
- {
- try
- {
- Clipboard.SetText(strData);
- }
- catch
- {
- }
- }
///
/// 取得GUID
@@ -752,23 +695,6 @@ public static void ProcessStart(string fileName, string arguments = "")
}
}
- 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;
- }
-
///
/// 获取系统hosts
///
@@ -958,12 +884,13 @@ public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool ru
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 @@ public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool ru
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 @@ public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool ru
}
}
- 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();
- }
- }
-
- ///
- /// Auto Start via TaskService
- ///
- ///
- ///
- ///
- ///
- 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
}
}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Common/WindowsUtils.cs b/v2rayN/v2rayN/Common/WindowsUtils.cs
new file mode 100644
index 0000000000..09f13cc1bf
--- /dev/null
+++ b/v2rayN/v2rayN/Common/WindowsUtils.cs
@@ -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
+ {
+
+ ///
+ /// 获取剪贴板数
+ ///
+ ///
+ 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;
+ }
+
+ ///
+ /// 拷贝至剪贴板
+ ///
+ ///
+ public static void SetClipboardData(string strData)
+ {
+ try
+ {
+ Clipboard.SetText(strData);
+ }
+ catch
+ {
+ }
+ }
+ ///
+ /// Auto Start via TaskService
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Enums/EViewAction.cs b/v2rayN/v2rayN/Enums/EViewAction.cs
index 2db8b30f13..312e7ff779 100644
--- a/v2rayN/v2rayN/Enums/EViewAction.cs
+++ b/v2rayN/v2rayN/Enums/EViewAction.cs
@@ -10,6 +10,8 @@ public enum EViewAction
ShareSub,
ShareServer,
ShowHideWindow,
+ ScanScreenTask,
+ Shutdown,
SubEditWindow,
RoutingRuleSettingWindow,
RoutingRuleDetailsWindow,
@@ -24,10 +26,10 @@ public enum EViewAction
DispatcherRefreshConnections,
DispatcherRefreshProxyGroups,
DispatcherProxiesDelayTest,
-
DispatcherStatistics,
DispatcherServerAvailability,
DispatcherReload,
DispatcherRefreshServersBiz,
+ DispatcherRefreshIcon,
}
}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Handler/CoreHandler.cs b/v2rayN/v2rayN/Handler/CoreHandler.cs
index f21f9dac86..37866d0f0d 100644
--- a/v2rayN/v2rayN/Handler/CoreHandler.cs
+++ b/v2rayN/v2rayN/Handler/CoreHandler.cs
@@ -46,11 +46,11 @@ public void LoadCore(ProfileItem? node)
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);
diff --git a/v2rayN/v2rayN/Handler/HotkeyHandler.cs b/v2rayN/v2rayN/Handler/HotkeyHandler.cs
index 31a733c46d..d91cddeb95 100644
--- a/v2rayN/v2rayN/Handler/HotkeyHandler.cs
+++ b/v2rayN/v2rayN/Handler/HotkeyHandler.cs
@@ -43,7 +43,7 @@ private void Init()
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;
diff --git a/v2rayN/v2rayN/Handler/MainFormHandler.cs b/v2rayN/v2rayN/Handler/MainFormHandler.cs
index e2f37a2a48..8547277bfe 100644
--- a/v2rayN/v2rayN/Handler/MainFormHandler.cs
+++ b/v2rayN/v2rayN/Handler/MainFormHandler.cs
@@ -156,71 +156,7 @@ public void Export2ClientConfig(ProfileItem item, Config config)
}
}
- public void UpdateTask(Config config, Action update)
- {
- Task.Run(() => UpdateTaskRunSubscription(config, update));
- Task.Run(() => UpdateTaskRunGeo(config, update));
- }
-
- private async Task UpdateTaskRunSubscription(Config config, Action 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 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 handler, Action update)
+ public void RegisterGlobalHotkey(Config config, Action handler, Action? update)
{
HotkeyHandler.Instance.UpdateViewEvent += update;
HotkeyHandler.Instance.HotkeyTriggerEvent += handler;
@@ -240,7 +176,7 @@ public void RegisterSystemColorSet(Config config, Window window, Action up
{
if (wParam == IntPtr.Zero && Marshal.PtrToStringUni(lParam) == "ImmersiveColorSet")
{
- update(!Utils.IsLightTheme());
+ update(!WindowsUtils.IsLightTheme());
}
}
}
diff --git a/v2rayN/v2rayN/Models/ConfigItems.cs b/v2rayN/v2rayN/Models/ConfigItems.cs
index 031b013448..b7c9c46fed 100644
--- a/v2rayN/v2rayN/Models/ConfigItems.cs
+++ b/v2rayN/v2rayN/Models/ConfigItems.cs
@@ -1,5 +1,4 @@
-using System.Windows.Input;
-using v2rayN.Enums;
+using v2rayN.Enums;
namespace v2rayN.Models
{
@@ -152,7 +151,7 @@ public class KeyEventItem
public bool Shift { get; set; }
- public Key? KeyCode { get; set; }
+ public int? KeyCode { get; set; }
}
[Serializable]
diff --git a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
index fcff69a4ab..50afd9b56f 100644
--- a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
@@ -3,13 +3,10 @@
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 @@ public class MainWindowViewModel : MyReactiveObject
public ReactiveCommand NotifyLeftClickCmd { get; }
- [Reactive]
- public Icon NotifyIcon { get; set; }
-
- [Reactive]
- public ImageSource AppIcon { get; set; }
-
#endregion Menu
#region System Proxy
@@ -259,9 +250,9 @@ public MainWindowViewModel(Func? updateView)
{
AddServerViaClipboard();
});
- AddServerViaScanCmd = ReactiveCommand.CreateFromTask(() =>
+ AddServerViaScanCmd = ReactiveCommand.Create(() =>
{
- return ScanScreenTaskAsync();
+ _updateView?.Invoke(EViewAction.ScanScreenTask, null);
});
//Subscription
@@ -390,9 +381,7 @@ private void Init()
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 @@ public void SetStatisticsResult(ServerSpeedItem update)
}
}
- 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 @@ public void MyAppExit(bool blWindowsShutDown)
catch { }
finally
{
- Application.Current.Shutdown();
+ _updateView?.Invoke(EViewAction.Shutdown, null);
}
}
@@ -613,7 +576,7 @@ public void AddServer(bool blNew, EConfigType eConfigType)
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 @@ public void AddServerViaClipboard()
}
}
- 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 @@ private async Task LoadCore()
{
await Task.Run(() =>
{
+ if (_config.tunModeItem.enableTun)
+ {
+ Thread.Sleep(1000);
+ WindowsUtils.RemoveTunDevice();
+ }
+
var node = ConfigHandler.GetDefaultServer(_config);
_coreHandler.LoadCore(node);
});
@@ -914,8 +873,7 @@ private void ChangeSystemProxyStatus(ESysProxyType type, bool blChange)
if (blChange)
{
- NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);
- AppIcon = MainFormHandler.Instance.GetAppIcon(_config);
+ _updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
}
}
@@ -966,8 +924,7 @@ private void RoutingSelectedChanged(bool c)
{
_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 @@ private void AutoHideStartup()
}
#endregion UI
+
+ #region UpdateTask
+
+ private void RegUpdateTask(Config config, Action update)
+ {
+ Task.Run(() => UpdateTaskRunSubscription(config, update));
+ Task.Run(() => UpdateTaskRunGeo(config, update));
+ }
+
+ private async Task UpdateTaskRunSubscription(Config config, Action 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 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
}
}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs b/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs
index a504d20d2a..68f1761392 100644
--- a/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs
@@ -739,7 +739,7 @@ public void Export2ShareUrl()
}
if (sb.Length > 0)
{
- Utils.SetClipboardData(sb.ToString());
+ WindowsUtils.SetClipboardData(sb.ToString());
_noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully);
}
}
diff --git a/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs
index 17715d932f..b1b08f7c01 100644
--- a/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs
@@ -202,7 +202,7 @@ public void RuleExportSelected()
}
if (lst.Count > 0)
{
- Utils.SetClipboardData(JsonUtils.Serialize(lst));
+ WindowsUtils.SetClipboardData(JsonUtils.Serialize(lst));
//_noticeHandler?.Enqueue(ResUI.OperationSuccess"));
}
}
@@ -283,7 +283,7 @@ private void ImportRulesFromFile()
private void ImportRulesFromClipboard()
{
- var clipboardData = Utils.GetClipboardData();
+ var clipboardData = WindowsUtils.GetClipboardData();
if (AddBatchRoutingRules(SelectedRouting, clipboardData) == 0)
{
RefreshRulesItems();
diff --git a/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs
index 8070a86ae9..8e17e499e0 100644
--- a/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs
@@ -50,7 +50,7 @@ private void RestoreUI()
{
if (FollowSystemTheme)
{
- ModifyTheme(!Utils.IsLightTheme());
+ ModifyTheme(!WindowsUtils.IsLightTheme());
}
else
{
@@ -104,7 +104,7 @@ private void BindingUI()
ConfigHandler.SaveConfig(_config);
if (FollowSystemTheme)
{
- ModifyTheme(!Utils.IsLightTheme());
+ ModifyTheme(!WindowsUtils.IsLightTheme());
}
else
{
@@ -173,8 +173,7 @@ public void ModifyTheme(bool isDarkTheme)
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)
diff --git a/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs b/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs
index 1ce39b9e75..43a22f0dbb 100644
--- a/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs
+++ b/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs
@@ -38,8 +38,7 @@ public AddServer2Window(ProfileItem profileItem)
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)
diff --git a/v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs b/v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs
index 8fbe8f2f8e..b12bb6cc20 100644
--- a/v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs
@@ -30,7 +30,7 @@ public GlobalHotkeySettingWindow()
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 @@ private void TxtGlobalHotkey_PreviewKeyDown(object sender, KeyEventArgs e)
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 @@ private string KeyEventItemToString(KeyEventItem item)
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 @@ private void BindingData()
{
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 @@ private void btnReset_Click(object sender, RoutedEventArgs e)
_TextBoxKeyEventItem[k].Alt = false;
_TextBoxKeyEventItem[k].Control = false;
_TextBoxKeyEventItem[k].Shift = false;
- _TextBoxKeyEventItem[k].KeyCode = Key.None;
+ _TextBoxKeyEventItem[k].KeyCode = (int)Key.None;
}
BindingData();
}
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs
index d93a3227ae..bfe29129ce 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs
@@ -37,6 +37,8 @@ public MainWindow()
ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
+ MainFormHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
+
this.WhenActivated(disposables =>
{
//servers
@@ -106,10 +108,8 @@ public MainWindow()
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 @@ public MainWindow()
AddHelpMenuItem();
}
+ #region Event
+
private bool UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
@@ -246,12 +248,52 @@ private bool UpdateViewHandler(EViewAction action, object? obj)
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 @@ private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
break;
case Key.S:
- ViewModel?.ScanScreenTaskAsync().ContinueWith(_ => { });
+ ScanScreenTaskAsync().ContinueWith(_ => { });
break;
}
}
@@ -320,6 +362,21 @@ private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
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
diff --git a/v2rayN/v2rayN/Views/MsgView.xaml.cs b/v2rayN/v2rayN/Views/MsgView.xaml.cs
index e00574a7ce..a8877cbe7e 100644
--- a/v2rayN/v2rayN/Views/MsgView.xaml.cs
+++ b/v2rayN/v2rayN/Views/MsgView.xaml.cs
@@ -99,13 +99,13 @@ private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEven
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)