2019-10-11 06:15:20 +00:00
|
|
|
|
using Microsoft.Win32;
|
2023-01-04 09:17:43 +00:00
|
|
|
|
using Microsoft.Win32.TaskScheduler;
|
2024-01-16 03:05:02 +00:00
|
|
|
|
using System.Collections.Specialized;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
using System.Diagnostics;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
using System.Drawing;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.NetworkInformation;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Reflection;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Security.Principal;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
2023-04-04 07:59:28 +00:00
|
|
|
|
using System.Windows;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
using System.Windows.Interop;
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
using System.Windows.Media.Imaging;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
using ZXing;
|
|
|
|
|
using ZXing.Common;
|
|
|
|
|
using ZXing.QrCode;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
using ZXing.Windows.Compatibility;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
namespace v2rayN
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
internal class Utils
|
2021-01-06 11:54:15 +00:00
|
|
|
|
{
|
2019-10-11 06:15:20 +00:00
|
|
|
|
#region 资源Json操作
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取嵌入文本资源
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="res"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string GetEmbedText(string res)
|
|
|
|
|
{
|
|
|
|
|
string result = string.Empty;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-03-14 19:25:40 +00:00
|
|
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
2023-02-19 04:18:08 +00:00
|
|
|
|
using Stream? stream = assembly.GetManifestResourceStream(res);
|
|
|
|
|
ArgumentNullException.ThrowIfNull(stream);
|
2023-02-17 06:36:28 +00:00
|
|
|
|
using StreamReader reader = new(stream);
|
|
|
|
|
result = reader.ReadToEnd();
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取得存储资源
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2023-02-20 10:16:30 +00:00
|
|
|
|
public static string? LoadResource(string res)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2023-02-20 10:16:30 +00:00
|
|
|
|
if (!File.Exists(res)) return null;
|
|
|
|
|
return File.ReadAllText(res);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2023-02-20 10:16:30 +00:00
|
|
|
|
return null;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion 资源Json操作
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region 转换函数
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// List<string>转逗号分隔的字符串
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="lst"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string List2String(List<string> lst, bool wrap = false)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-01-08 12:27:36 +00:00
|
|
|
|
if (lst == null)
|
|
|
|
|
{
|
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (wrap)
|
|
|
|
|
{
|
2023-02-17 07:17:01 +00:00
|
|
|
|
return string.Join("," + Environment.NewLine, lst);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-02-20 10:16:30 +00:00
|
|
|
|
return string.Join(",", lst);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2019-10-11 06:15:20 +00:00
|
|
|
|
/// <summary>
|
2020-04-20 11:49:27 +00:00
|
|
|
|
/// 逗号分隔的字符串,转List<string>
|
2019-10-11 06:15:20 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static List<string> String2List(string str)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-04-20 11:49:27 +00:00
|
|
|
|
str = str.Replace(Environment.NewLine, "");
|
2023-02-17 07:17:01 +00:00
|
|
|
|
return new List<string>(str.Split(',', StringSplitOptions.RemoveEmptyEntries));
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return new List<string>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 05:21:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 逗号分隔的字符串,先排序后转List<string>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static List<string> String2ListSorted(string str)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
str = str.Replace(Environment.NewLine, "");
|
2023-02-17 07:17:01 +00:00
|
|
|
|
List<string> list = new(str.Split(',', StringSplitOptions.RemoveEmptyEntries));
|
|
|
|
|
list.Sort();
|
|
|
|
|
return list;
|
2022-04-01 05:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2022-04-01 05:21:22 +00:00
|
|
|
|
return new List<string>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-11 06:15:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Base64编码
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="plainText"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string Base64Encode(string plainText)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-03-14 19:27:31 +00:00
|
|
|
|
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return Convert.ToBase64String(plainTextBytes);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog("Base64Encode", ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Base64解码
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="plainText"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string Base64Decode(string plainText)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
plainText = plainText.Trim()
|
2019-12-11 03:42:41 +00:00
|
|
|
|
.Replace(Environment.NewLine, "")
|
2019-10-11 06:15:20 +00:00
|
|
|
|
.Replace("\n", "")
|
|
|
|
|
.Replace("\r", "")
|
2023-03-20 06:03:50 +00:00
|
|
|
|
.Replace('_', '/')
|
|
|
|
|
.Replace('-', '+')
|
2019-10-11 06:15:20 +00:00
|
|
|
|
.Replace(" ", "");
|
|
|
|
|
|
|
|
|
|
if (plainText.Length % 4 > 0)
|
|
|
|
|
{
|
|
|
|
|
plainText = plainText.PadRight(plainText.Length + 4 - plainText.Length % 4, '=');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte[] data = Convert.FromBase64String(plainText);
|
|
|
|
|
return Encoding.UTF8.GetString(data);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog("Base64Decode", ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转Int
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
/// <returns></returns>
|
2024-01-15 09:11:00 +00:00
|
|
|
|
public static int ToInt(object? obj)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-01-15 09:11:00 +00:00
|
|
|
|
return Convert.ToInt32(obj ?? string.Empty);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2024-01-10 09:44:55 +00:00
|
|
|
|
catch //(Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-03-20 06:03:50 +00:00
|
|
|
|
//SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2022-03-13 02:41:04 +00:00
|
|
|
|
public static bool ToBool(object obj)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return Convert.ToBoolean(obj);
|
|
|
|
|
}
|
2024-01-10 09:44:55 +00:00
|
|
|
|
catch //(Exception ex)
|
2022-03-13 02:41:04 +00:00
|
|
|
|
{
|
2023-03-20 06:03:50 +00:00
|
|
|
|
//SaveLog(ex.Message, ex);
|
2022-03-13 02:41:04 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
public static string ToString(object obj)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
return obj?.ToString() ?? string.Empty;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2024-01-10 09:44:55 +00:00
|
|
|
|
catch// (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-03-20 06:03:50 +00:00
|
|
|
|
//SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// byte 转成 有两位小数点的 方便阅读的数据
|
|
|
|
|
/// 比如 2.50 MB
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="amount">bytes</param>
|
|
|
|
|
/// <param name="result">转换之后的数据</param>
|
|
|
|
|
/// <param name="unit">单位</param>
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static void ToHumanReadable(long amount, out double result, out string unit)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2020-03-14 19:25:40 +00:00
|
|
|
|
uint factor = 1024u;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
//long KBs = amount / factor;
|
|
|
|
|
long KBs = amount;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (KBs > 0)
|
|
|
|
|
{
|
|
|
|
|
// multi KB
|
2023-01-01 11:42:01 +00:00
|
|
|
|
long MBs = KBs / factor;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (MBs > 0)
|
|
|
|
|
{
|
|
|
|
|
// multi MB
|
2023-01-01 11:42:01 +00:00
|
|
|
|
long GBs = MBs / factor;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (GBs > 0)
|
|
|
|
|
{
|
|
|
|
|
// multi GB
|
2023-04-10 09:30:27 +00:00
|
|
|
|
long TBs = GBs / factor;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (TBs > 0)
|
|
|
|
|
{
|
2023-04-16 12:45:47 +00:00
|
|
|
|
result = TBs + ((GBs % factor) / (factor + 0.0));
|
2019-10-11 06:15:20 +00:00
|
|
|
|
unit = "TB";
|
|
|
|
|
return;
|
2023-04-10 09:30:27 +00:00
|
|
|
|
}
|
2023-04-16 12:45:47 +00:00
|
|
|
|
result = GBs + ((MBs % factor) / (factor + 0.0));
|
2019-10-11 06:15:20 +00:00
|
|
|
|
unit = "GB";
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-04-16 12:45:47 +00:00
|
|
|
|
result = MBs + ((KBs % factor) / (factor + 0.0));
|
2019-10-11 06:15:20 +00:00
|
|
|
|
unit = "MB";
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-04-16 12:45:47 +00:00
|
|
|
|
result = KBs + ((amount % factor) / (factor + 0.0));
|
2019-10-11 06:15:20 +00:00
|
|
|
|
unit = "KB";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = amount;
|
|
|
|
|
unit = "B";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static string HumanFy(long amount)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2020-03-14 19:26:54 +00:00
|
|
|
|
ToHumanReadable(amount, out double result, out string unit);
|
2020-02-17 05:55:58 +00:00
|
|
|
|
return $"{string.Format("{0:f1}", result)} {unit}";
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-06 11:54:15 +00:00
|
|
|
|
public static string UrlEncode(string url)
|
|
|
|
|
{
|
2022-03-31 12:19:15 +00:00
|
|
|
|
return Uri.EscapeDataString(url);
|
|
|
|
|
//return HttpUtility.UrlEncode(url);
|
2021-01-06 11:54:15 +00:00
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2021-01-06 11:54:15 +00:00
|
|
|
|
public static string UrlDecode(string url)
|
|
|
|
|
{
|
2024-01-16 03:05:02 +00:00
|
|
|
|
return Uri.UnescapeDataString(url);
|
|
|
|
|
//return HttpUtility.UrlDecode(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static NameValueCollection ParseQueryString(string query)
|
|
|
|
|
{
|
|
|
|
|
var result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
if (IsNullOrEmpty(query))
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parts = query[1..].Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
foreach (var part in parts)
|
|
|
|
|
{
|
|
|
|
|
var keyValue = part.Split(['=']);
|
|
|
|
|
if (keyValue.Length != 2)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
var key = Uri.UnescapeDataString(keyValue[0]);
|
|
|
|
|
var val = Uri.UnescapeDataString(keyValue[1]);
|
|
|
|
|
|
2024-02-21 02:17:28 +00:00
|
|
|
|
if (result[key] is null)
|
|
|
|
|
{
|
|
|
|
|
result.Add(key, val);
|
|
|
|
|
}
|
2024-01-16 03:05:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
2021-01-06 11:54:15 +00:00
|
|
|
|
}
|
2022-05-12 00:52:40 +00:00
|
|
|
|
|
|
|
|
|
public static string GetMD5(string str)
|
|
|
|
|
{
|
|
|
|
|
byte[] byteOld = Encoding.UTF8.GetBytes(str);
|
2023-02-17 06:36:28 +00:00
|
|
|
|
byte[] byteNew = MD5.HashData(byteOld);
|
|
|
|
|
StringBuilder sb = new(32);
|
2022-05-12 00:52:40 +00:00
|
|
|
|
foreach (byte b in byteNew)
|
|
|
|
|
{
|
|
|
|
|
sb.Append(b.ToString("x2"));
|
|
|
|
|
}
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static ImageSource IconToImageSource(Icon icon)
|
|
|
|
|
{
|
|
|
|
|
return Imaging.CreateBitmapSourceFromHIcon(
|
|
|
|
|
icon.Handle,
|
|
|
|
|
new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),
|
|
|
|
|
BitmapSizeOptions.FromEmptyOptions());
|
|
|
|
|
}
|
2022-05-12 00:52:40 +00:00
|
|
|
|
|
2023-04-06 07:09:49 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// idn to idc
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="url"></param>
|
|
|
|
|
/// <returns></returns>
|
2022-12-13 12:02:45 +00:00
|
|
|
|
public static string GetPunycode(string url)
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(url))
|
2022-12-13 12:02:45 +00:00
|
|
|
|
{
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
Uri uri = new(url);
|
2024-03-07 01:06:35 +00:00
|
|
|
|
if (uri.Host == uri.IdnHost || uri.Host == $"[{uri.IdnHost}]")
|
2022-12-13 12:02:45 +00:00
|
|
|
|
{
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return url.Replace(uri.Host, uri.IdnHost);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 03:40:28 +00:00
|
|
|
|
public static bool IsBase64String(string plainText)
|
|
|
|
|
{
|
|
|
|
|
var buffer = new Span<byte>(new byte[plainText.Length]);
|
|
|
|
|
return Convert.TryFromBase64String(plainText, buffer, out int _);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-28 02:22:55 +00:00
|
|
|
|
public static string Convert2Comma(string text)
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(text))
|
2023-04-28 02:22:55 +00:00
|
|
|
|
{
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
return text.Replace(",", ",").Replace(Environment.NewLine, ",");
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion 转换函数
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region 数据检查
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 判断输入的是否是数字
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="oText"></param>
|
|
|
|
|
/// <returns></returns>
|
2024-02-19 09:43:36 +00:00
|
|
|
|
public static bool IsNumeric(string oText)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-03-14 19:27:31 +00:00
|
|
|
|
int var1 = ToInt(oText);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 文本
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="text"></param>
|
|
|
|
|
/// <returns></returns>
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static bool IsNullOrEmpty(string? text)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-03-23 10:26:04 +00:00
|
|
|
|
if (string.IsNullOrWhiteSpace(text))
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-02-19 11:15:02 +00:00
|
|
|
|
if (text == "null")
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 验证IP地址是否合法
|
|
|
|
|
/// </summary>
|
2023-04-14 12:49:36 +00:00
|
|
|
|
/// <param name="ip"></param>
|
2019-10-11 06:15:20 +00:00
|
|
|
|
public static bool IsIP(string ip)
|
|
|
|
|
{
|
|
|
|
|
//如果为空
|
|
|
|
|
if (IsNullOrEmpty(ip))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//清除要验证字符串中的空格
|
|
|
|
|
//ip = ip.TrimEx();
|
|
|
|
|
//可能是CIDR
|
|
|
|
|
if (ip.IndexOf(@"/") > 0)
|
|
|
|
|
{
|
2020-03-14 19:25:40 +00:00
|
|
|
|
string[] cidr = ip.Split('/');
|
2019-10-11 06:15:20 +00:00
|
|
|
|
if (cidr.Length == 2)
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
if (!IsNumeric(cidr[0]))
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
ip = cidr[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//模式字符串
|
|
|
|
|
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
|
|
|
|
|
|
|
|
|
|
//验证
|
|
|
|
|
return IsMatch(ip, pattern);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 验证Domain地址是否合法
|
|
|
|
|
/// </summary>
|
2023-04-14 12:49:36 +00:00
|
|
|
|
/// <param name="domain"></param>
|
2019-10-11 06:15:20 +00:00
|
|
|
|
public static bool IsDomain(string domain)
|
|
|
|
|
{
|
|
|
|
|
//如果为空
|
|
|
|
|
if (IsNullOrEmpty(domain))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-27 08:20:13 +00:00
|
|
|
|
return Uri.CheckHostName(domain) == UriHostNameType.Dns;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input">输入字符串</param>
|
2023-04-14 12:49:36 +00:00
|
|
|
|
/// <param name="pattern">模式字符串</param>
|
2019-10-11 06:15:20 +00:00
|
|
|
|
public static bool IsMatch(string input, string pattern)
|
|
|
|
|
{
|
|
|
|
|
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-21 02:09:39 +00:00
|
|
|
|
public static bool IsIpv6(string ip)
|
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
if (IPAddress.TryParse(ip, out IPAddress? address))
|
2021-03-21 02:09:39 +00:00
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
return address.AddressFamily switch
|
2021-03-21 02:09:39 +00:00
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
AddressFamily.InterNetwork => false,
|
|
|
|
|
AddressFamily.InterNetworkV6 => true,
|
|
|
|
|
_ => false,
|
|
|
|
|
};
|
2021-03-21 02:09:39 +00:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion 数据检查
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region 测速
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取得本机 IP Address
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2023-01-01 11:42:01 +00:00
|
|
|
|
//public static List<string> GetHostIPAddress()
|
|
|
|
|
//{
|
|
|
|
|
// List<string> lstIPAddress = new List<string>();
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// IPHostEntry IpEntry = Dns.GetHostEntry(Dns.GetHostName());
|
|
|
|
|
// foreach (IPAddress ipa in IpEntry.AddressList)
|
|
|
|
|
// {
|
|
|
|
|
// if (ipa.AddressFamily == AddressFamily.InterNetwork)
|
|
|
|
|
// lstIPAddress.Add(ipa.ToString());
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// catch (Exception ex)
|
|
|
|
|
// {
|
|
|
|
|
// SaveLog(ex.Message, ex);
|
|
|
|
|
// }
|
|
|
|
|
// return lstIPAddress;
|
|
|
|
|
//}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
2022-02-26 04:27:59 +00:00
|
|
|
|
public static void SetSecurityProtocol(bool enableSecurityProtocolTls13)
|
2019-12-12 02:16:09 +00:00
|
|
|
|
{
|
2022-02-26 04:27:59 +00:00
|
|
|
|
if (enableSecurityProtocolTls13)
|
2022-01-08 12:27:36 +00:00
|
|
|
|
{
|
2022-04-11 11:16:35 +00:00
|
|
|
|
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
|
2022-01-08 12:27:36 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-04-11 11:16:35 +00:00
|
|
|
|
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
|
2022-01-08 12:27:36 +00:00
|
|
|
|
}
|
2019-12-12 02:16:09 +00:00
|
|
|
|
ServicePointManager.DefaultConnectionLimit = 256;
|
|
|
|
|
}
|
2022-01-12 13:05:03 +00:00
|
|
|
|
|
|
|
|
|
public static bool PortInUse(int port)
|
|
|
|
|
{
|
|
|
|
|
bool inUse = false;
|
2022-03-17 11:07:06 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
|
|
|
|
|
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
|
2022-01-12 13:05:03 +00:00
|
|
|
|
|
2022-03-17 11:07:06 +00:00
|
|
|
|
var lstIpEndPoints = new List<IPEndPoint>(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
2022-01-12 13:05:03 +00:00
|
|
|
|
|
2022-03-17 11:07:06 +00:00
|
|
|
|
foreach (IPEndPoint endPoint in ipEndPoints)
|
2022-01-12 13:05:03 +00:00
|
|
|
|
{
|
2022-03-17 11:07:06 +00:00
|
|
|
|
if (endPoint.Port == port)
|
|
|
|
|
{
|
|
|
|
|
inUse = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-01-12 13:05:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-17 11:07:06 +00:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2022-03-17 11:07:06 +00:00
|
|
|
|
}
|
2022-01-12 13:05:03 +00:00
|
|
|
|
return inUse;
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2024-03-02 02:00:28 +00:00
|
|
|
|
public static int GetFreePort(int defaultPort = 9090)
|
2024-02-08 06:01:33 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (!Utils.PortInUse(defaultPort))
|
2024-02-08 06:01:33 +00:00
|
|
|
|
{
|
|
|
|
|
return defaultPort;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TcpListener l = new(IPAddress.Loopback, 0);
|
|
|
|
|
l.Start();
|
|
|
|
|
int port = ((IPEndPoint)l.LocalEndpoint).Port;
|
|
|
|
|
l.Stop();
|
|
|
|
|
return port;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
2024-03-02 02:00:28 +00:00
|
|
|
|
return 59090;
|
2024-02-08 06:01:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion 测速
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region 杂项
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取得版本
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2022-02-20 07:16:00 +00:00
|
|
|
|
public static string GetVersion(bool blFull = true)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string location = GetExePath();
|
2022-02-20 07:16:00 +00:00
|
|
|
|
if (blFull)
|
|
|
|
|
{
|
2023-03-25 09:50:32 +00:00
|
|
|
|
return string.Format("v2rayN - V{0} - {1}",
|
2024-01-06 02:41:07 +00:00
|
|
|
|
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
|
2022-02-20 07:16:00 +00:00
|
|
|
|
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return string.Format("v2rayN/{0}",
|
2024-01-06 02:41:07 +00:00
|
|
|
|
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
|
2022-02-20 07:16:00 +00:00
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取剪贴板数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2023-02-19 04:18:08 +00:00
|
|
|
|
public static string? GetClipboardData()
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-03-20 06:03:50 +00:00
|
|
|
|
string? strData = string.Empty;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IDataObject data = Clipboard.GetDataObject();
|
2021-05-13 12:51:20 +00:00
|
|
|
|
if (data.GetDataPresent(DataFormats.UnicodeText))
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-03-20 06:03:50 +00:00
|
|
|
|
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
return strData;
|
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
return strData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 拷贝至剪贴板
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static void SetClipboardData(string strData)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Clipboard.SetText(strData);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取得GUID
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2022-01-28 13:02:25 +00:00
|
|
|
|
public static string GetGUID(bool full = true)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-01-28 13:02:25 +00:00
|
|
|
|
if (full)
|
|
|
|
|
{
|
|
|
|
|
return Guid.NewGuid().ToString("D");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0).ToString();
|
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// IsAdministrator
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static bool IsAdministrator()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
WindowsIdentity current = WindowsIdentity.GetCurrent();
|
|
|
|
|
WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);
|
|
|
|
|
//WindowsBuiltInRole可以枚举出很多权限,例如系统用户、User、Guest等等
|
|
|
|
|
return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
|
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-10 12:16:30 +00:00
|
|
|
|
public static string GetDownloadFileName(string url)
|
|
|
|
|
{
|
2022-06-22 01:48:00 +00:00
|
|
|
|
var fileName = Path.GetFileName(url);
|
2021-10-10 12:16:30 +00:00
|
|
|
|
fileName += "_temp";
|
|
|
|
|
|
|
|
|
|
return fileName;
|
|
|
|
|
}
|
2022-03-17 11:07:06 +00:00
|
|
|
|
|
2023-02-19 04:18:08 +00:00
|
|
|
|
public static IPAddress? GetDefaultGateway()
|
2022-03-17 11:07:06 +00:00
|
|
|
|
{
|
|
|
|
|
return NetworkInterface
|
|
|
|
|
.GetAllNetworkInterfaces()
|
|
|
|
|
.Where(n => n.OperationalStatus == OperationalStatus.Up)
|
|
|
|
|
.Where(n => n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
|
|
|
|
|
.SelectMany(n => n.GetIPProperties()?.GatewayAddresses)
|
|
|
|
|
.Select(g => g?.Address)
|
|
|
|
|
.Where(a => a != null)
|
|
|
|
|
// .Where(a => a.AddressFamily == AddressFamily.InterNetwork)
|
|
|
|
|
// .Where(a => Array.FindIndex(a.GetAddressBytes(), b => b != 0) >= 0)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool IsGuidByParse(string strSrc)
|
|
|
|
|
{
|
|
|
|
|
return Guid.TryParse(strSrc, out Guid g);
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static void ProcessStart(string fileName)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Process.Start(new ProcessStartInfo(fileName) { UseShellExecute = true });
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-05-12 08:19:09 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-28 11:53:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取系统hosts
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static Dictionary<string, string> GetSystemHosts()
|
|
|
|
|
{
|
|
|
|
|
var systemHosts = new Dictionary<string, string>();
|
|
|
|
|
var hostfile = @"C:\Windows\System32\drivers\etc\hosts";
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (File.Exists(hostfile))
|
|
|
|
|
{
|
|
|
|
|
var hosts = File.ReadAllText(hostfile).Replace("\r", "");
|
|
|
|
|
var hostsList = hosts.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
|
|
|
|
foreach (var host in hostsList)
|
|
|
|
|
{
|
|
|
|
|
if (host.StartsWith("#")) continue;
|
|
|
|
|
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
if (hostItem.Length < 2) continue;
|
|
|
|
|
systemHosts.Add(hostItem[1], hostItem[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
|
|
|
|
}
|
|
|
|
|
return systemHosts;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion 杂项
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region TempPath
|
|
|
|
|
|
2024-01-31 01:56:47 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取启动了应用程序的可执行文件的路径
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string GetPath(string fileName)
|
|
|
|
|
{
|
|
|
|
|
string startupPath = StartupPath();
|
|
|
|
|
if (IsNullOrEmpty(fileName))
|
|
|
|
|
{
|
|
|
|
|
return startupPath;
|
|
|
|
|
}
|
|
|
|
|
return Path.Combine(startupPath, fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取启动了应用程序的可执行文件的路径及文件名
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string GetExePath()
|
|
|
|
|
{
|
|
|
|
|
return Environment.ProcessPath ?? string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string StartupPath()
|
|
|
|
|
{
|
|
|
|
|
return AppDomain.CurrentDomain.BaseDirectory;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-20 12:40:07 +00:00
|
|
|
|
public static string GetTempPath(string filename = "")
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2022-05-12 01:50:48 +00:00
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "guiTemps");
|
2019-12-12 02:16:09 +00:00
|
|
|
|
if (!Directory.Exists(_tempPath))
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2019-12-12 02:16:09 +00:00
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(filename))
|
2022-03-20 12:40:07 +00:00
|
|
|
|
{
|
|
|
|
|
return _tempPath;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
2020-11-23 13:18:44 +00:00
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
public static string UnGzip(byte[] buf)
|
|
|
|
|
{
|
2023-02-17 06:36:28 +00:00
|
|
|
|
using MemoryStream sb = new();
|
|
|
|
|
using GZipStream input = new(new MemoryStream(buf), CompressionMode.Decompress, false);
|
|
|
|
|
input.CopyTo(sb);
|
|
|
|
|
sb.Position = 0;
|
|
|
|
|
return new StreamReader(sb, Encoding.UTF8).ReadToEnd();
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-20 12:40:07 +00:00
|
|
|
|
public static string GetBackupPath(string filename)
|
|
|
|
|
{
|
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "guiBackups");
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2022-03-20 12:40:07 +00:00
|
|
|
|
public static string GetConfigPath(string filename = "")
|
|
|
|
|
{
|
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "guiConfigs");
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(filename))
|
2022-03-20 12:40:07 +00:00
|
|
|
|
{
|
|
|
|
|
return _tempPath;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2024-01-10 02:43:48 +00:00
|
|
|
|
public static string GetBinPath(string filename, string? coreType = null)
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "bin");
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
|
|
|
|
if (coreType != null)
|
|
|
|
|
{
|
|
|
|
|
_tempPath = Path.Combine(_tempPath, coreType.ToString()!);
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(filename))
|
2023-02-10 03:22:03 +00:00
|
|
|
|
{
|
|
|
|
|
return _tempPath;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public static string GetLogPath(string filename = "")
|
|
|
|
|
{
|
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "guiLogs");
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(filename))
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
|
|
|
|
return _tempPath;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-02-04 04:50:38 +00:00
|
|
|
|
public static string GetFontsPath(string filename = "")
|
|
|
|
|
{
|
|
|
|
|
string _tempPath = Path.Combine(StartupPath(), "guiFonts");
|
|
|
|
|
if (!Directory.Exists(_tempPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(_tempPath);
|
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(filename))
|
2023-02-04 04:50:38 +00:00
|
|
|
|
{
|
|
|
|
|
return _tempPath;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Path.Combine(_tempPath, filename);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-20 12:40:07 +00:00
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion TempPath
|
2019-10-11 06:15:20 +00:00
|
|
|
|
|
|
|
|
|
#region scan screen
|
|
|
|
|
|
2023-04-05 12:53:05 +00:00
|
|
|
|
public static string ScanScreen(float dpiX, float dpiY)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2023-04-05 12:53:05 +00:00
|
|
|
|
var left = (int)(SystemParameters.WorkArea.Left);
|
|
|
|
|
var top = (int)(SystemParameters.WorkArea.Top);
|
|
|
|
|
var width = (int)(SystemParameters.WorkArea.Width / dpiX);
|
|
|
|
|
var height = (int)(SystemParameters.WorkArea.Height / dpiY);
|
|
|
|
|
|
|
|
|
|
using Bitmap fullImage = new Bitmap(width, height);
|
|
|
|
|
using (Graphics g = Graphics.FromImage(fullImage))
|
|
|
|
|
{
|
|
|
|
|
g.CopyFromScreen(left, top, 0, 0, fullImage.Size, CopyPixelOperation.SourceCopy);
|
|
|
|
|
}
|
|
|
|
|
int maxTry = 10;
|
|
|
|
|
for (int i = 0; i < maxTry; i++)
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-04-05 12:53:05 +00:00
|
|
|
|
int marginLeft = (int)((double)fullImage.Width * i / 2.5 / maxTry);
|
|
|
|
|
int marginTop = (int)((double)fullImage.Height * i / 2.5 / maxTry);
|
|
|
|
|
Rectangle cropRect = new(marginLeft, marginTop, fullImage.Width - marginLeft * 2, fullImage.Height - marginTop * 2);
|
|
|
|
|
Bitmap target = new(width, height);
|
2023-04-04 07:59:28 +00:00
|
|
|
|
|
2023-04-05 12:53:05 +00:00
|
|
|
|
double imageScale = (double)width / (double)cropRect.Width;
|
|
|
|
|
using (Graphics g = Graphics.FromImage(target))
|
2019-10-11 06:15:20 +00:00
|
|
|
|
{
|
2023-04-05 12:53:05 +00:00
|
|
|
|
g.DrawImage(fullImage, new Rectangle(0, 0, target.Width, target.Height),
|
|
|
|
|
cropRect,
|
|
|
|
|
GraphicsUnit.Pixel);
|
2023-02-17 06:36:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 12:53:05 +00:00
|
|
|
|
BitmapLuminanceSource source = new(target);
|
|
|
|
|
BinaryBitmap bitmap = new(new HybridBinarizer(source));
|
|
|
|
|
QRCodeReader reader = new();
|
|
|
|
|
Result result = reader.decode(bitmap);
|
|
|
|
|
if (result != null)
|
|
|
|
|
{
|
|
|
|
|
string ret = result.Text;
|
|
|
|
|
return ret;
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-16 12:16:50 +00:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2024-01-10 02:43:48 +00:00
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
2021-10-16 12:16:50 +00:00
|
|
|
|
}
|
2019-10-11 06:15:20 +00:00
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 12:53:05 +00:00
|
|
|
|
public static Tuple<float, float> GetDpiXY(Window window)
|
|
|
|
|
{
|
|
|
|
|
IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle();
|
|
|
|
|
Graphics g = Graphics.FromHwnd(hWnd);
|
|
|
|
|
|
|
|
|
|
return new(96 / g.DpiX, 96 / g.DpiY);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion scan screen
|
2022-07-01 12:50:47 +00:00
|
|
|
|
|
2024-01-31 01:56:47 +00:00
|
|
|
|
#region 开机自动启动等
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开机自动启动
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="run"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool run)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var autoRunName = $"{AutoRunName}_{GetMD5(StartupPath())}";
|
|
|
|
|
|
|
|
|
|
//delete first
|
|
|
|
|
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
|
|
|
|
if (IsAdministrator())
|
|
|
|
|
{
|
|
|
|
|
AutoStart(autoRunName, "", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (run)
|
|
|
|
|
{
|
2024-03-30 23:54:22 +00:00
|
|
|
|
string exePath = GetExePath();
|
2024-01-31 01:56:47 +00:00
|
|
|
|
if (IsAdministrator())
|
|
|
|
|
{
|
|
|
|
|
AutoStart(autoRunName, exePath, "");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-03-30 23:54:22 +00:00
|
|
|
|
RegWriteValue(AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
2024-01-31 01:56:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Logging.SaveLog(ex.Message, ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(taskName))
|
2024-01-31 01:56:47 +00:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(fileName))
|
2024-01-31 01:56:47 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
2024-03-30 23:54:22 +00:00
|
|
|
|
task.Actions.Add(new ExecAction(deamonFileName.AppendQuotes(), null, Path.GetDirectoryName(deamonFileName)));
|
2024-01-31 01:56:47 +00:00
|
|
|
|
|
|
|
|
|
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void RemoveTunDevice()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string pnputilPath = @"C:\Windows\System32\pnputil.exe";
|
|
|
|
|
string arg = $" /remove-device /deviceid \"wintun\"";
|
|
|
|
|
|
|
|
|
|
// 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 开机自动启动等
|
|
|
|
|
|
2022-07-01 12:50:47 +00:00
|
|
|
|
#region Windows API
|
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
[Flags]
|
|
|
|
|
public enum DWMWINDOWATTRIBUTE : uint
|
2022-07-01 12:50:47 +00:00
|
|
|
|
{
|
2023-01-01 11:42:01 +00:00
|
|
|
|
DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
|
|
|
|
|
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
2022-07-01 12:50:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
[DllImport("dwmapi.dll")]
|
|
|
|
|
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
2022-07-01 12:50:47 +00:00
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion Windows API
|
2019-10-11 06:15:20 +00:00
|
|
|
|
}
|
2024-03-16 03:38:41 +00:00
|
|
|
|
}
|