v2rayN/v2rayN/ServiceLib/Common/Utils.cs

1006 lines
26 KiB
C#
Raw Normal View History

2024-10-08 09:40:25 +00:00
using System.Collections.Specialized;
2019-10-11 06:15:20 +00:00
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
2024-08-26 10:45:41 +00:00
using System.Runtime.InteropServices;
2023-01-01 11:42:01 +00:00
using System.Security.Cryptography;
using System.Security.Principal;
2019-10-11 06:15:20 +00:00
using System.Text;
2025-01-30 09:10:05 +00:00
using CliWrap;
using CliWrap.Buffered;
2019-10-11 06:15:20 +00:00
namespace ServiceLib.Common;
public class Utils
2019-10-11 06:15:20 +00:00
{
private static readonly string _tag = "Utils";
2025-01-03 07:02:31 +00:00
#region
2019-10-11 06:15:20 +00:00
/// <summary>
/// Convert to comma-separated string
/// </summary>
/// <param name="lst"></param>
/// <param name="wrap"></param>
/// <returns></returns>
public static string List2String(List<string>? lst, bool wrap = false)
{
if (lst == null || lst.Count == 0)
2019-10-11 06:15:20 +00:00
{
return string.Empty;
}
2025-03-06 02:47:06 +00:00
var separator = wrap ? "," + Environment.NewLine : ",";
2025-03-06 02:47:06 +00:00
try
{
return string.Join(separator, lst);
2019-10-11 06:15:20 +00:00
}
catch (Exception ex)
2019-10-11 06:15:20 +00:00
{
Logging.SaveLog(_tag, ex);
return string.Empty;
2019-10-11 06:15:20 +00:00
}
}
2019-10-11 06:15:20 +00:00
/// <summary>
/// Comma-separated string
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static List<string>? String2List(string? str)
{
if (string.IsNullOrWhiteSpace(str))
{
return null;
}
try
2019-10-11 06:15:20 +00:00
{
str = str.Replace(Environment.NewLine, string.Empty);
return new List<string>(str.Split(',', StringSplitOptions.RemoveEmptyEntries));
2019-10-11 06:15:20 +00:00
}
catch (Exception ex)
2019-10-11 06:15:20 +00:00
{
Logging.SaveLog(_tag, ex);
return null;
2019-10-11 06:15:20 +00:00
}
}
/// <summary>
/// Comma-separated string, sorted and then converted to List
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static List<string>? String2ListSorted(string str)
{
var lst = String2List(str);
lst?.Sort();
return lst;
}
2019-10-11 06:15:20 +00:00
/// <summary>
/// Base64 Encode
/// </summary>
/// <param name="plainText"></param>
/// <param name="removePadding"></param>
/// <returns></returns>
public static string Base64Encode(string plainText, bool removePadding = false)
{
try
2022-03-13 02:41:04 +00:00
{
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
var base64 = Convert.ToBase64String(plainTextBytes);
if (removePadding)
{
base64 = base64.TrimEnd('=');
}
return base64;
2022-03-13 02:41:04 +00:00
}
catch (Exception ex)
2019-10-11 06:15:20 +00:00
{
Logging.SaveLog(_tag, ex);
2019-10-11 06:15:20 +00:00
}
return string.Empty;
}
/// <summary>
/// Base64 Decode
/// </summary>
/// <param name="plainText"></param>
/// <returns></returns>
public static string Base64Decode(string? plainText)
{
try
2019-10-11 06:15:20 +00:00
{
if (plainText.IsNullOrEmpty())
2025-03-06 02:47:06 +00:00
{
return string.Empty;
2019-10-11 06:15:20 +00:00
}
2025-03-06 02:47:06 +00:00
plainText = plainText.Trim()
.Replace(Environment.NewLine, "")
.Replace("\n", "")
.Replace("\r", "")
.Replace('_', '/')
.Replace('-', '+')
.Replace(" ", "");
2025-03-06 02:47:06 +00:00
if (plainText.Length % 4 > 0)
2019-10-11 06:15:20 +00:00
{
plainText = plainText.PadRight(plainText.Length + 4 - (plainText.Length % 4), '=');
2019-10-11 06:15:20 +00:00
}
var data = Convert.FromBase64String(plainText);
return Encoding.UTF8.GetString(data);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
2019-10-11 06:15:20 +00:00
}
return string.Empty;
}
public static bool ToBool(object obj)
{
try
{
return Convert.ToBoolean(obj);
}
catch
2021-01-06 11:54:15 +00:00
{
return false;
2021-01-06 11:54:15 +00:00
}
}
2023-04-14 12:49:36 +00:00
public static string ToString(object? obj)
{
try
2021-01-06 11:54:15 +00:00
{
return obj?.ToString() ?? string.Empty;
}
catch
{
return string.Empty;
2024-01-16 03:05:02 +00:00
}
}
2024-01-16 03:05:02 +00:00
public static string HumanFy(long amount)
{
if (amount <= 0)
2024-01-16 03:05:02 +00:00
{
return $"{amount:f1} B";
}
2024-01-16 03:05:02 +00:00
string[] units = ["KB", "MB", "GB", "TB", "PB"];
var unitIndex = 0;
double size = amount;
2024-11-01 06:54:23 +00:00
// Loop and divide by 1024 until a suitable unit is found
while (size >= 1024 && unitIndex < units.Length - 1)
{
size /= 1024;
unitIndex++;
}
2024-01-16 03:05:02 +00:00
return $"{size:f1} {units[unitIndex]}";
}
2024-01-16 03:05:02 +00:00
public static string UrlEncode(string url)
{
return Uri.EscapeDataString(url);
}
public static string UrlDecode(string url)
{
return Uri.UnescapeDataString(url);
}
public static NameValueCollection ParseQueryString(string query)
{
var result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
if (query.IsNullOrEmpty())
{
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
var parts = query[1..].Split('&', StringSplitOptions.RemoveEmptyEntries);
foreach (var part in parts)
2022-05-12 00:52:40 +00:00
{
var keyValue = part.Split('=');
if (keyValue.Length != 2)
2022-05-12 00:52:40 +00:00
{
continue;
}
var key = Uri.UnescapeDataString(keyValue.First());
var val = Uri.UnescapeDataString(keyValue.Last());
if (result[key] is null)
{
result.Add(key, val);
}
}
2024-11-01 06:54:23 +00:00
return result;
}
public static string GetMd5(string str)
{
if (string.IsNullOrEmpty(str))
{
return string.Empty;
2022-05-12 00:52:40 +00:00
}
2023-04-14 12:49:36 +00:00
try
2022-12-13 12:02:45 +00:00
{
var byteOld = Encoding.UTF8.GetBytes(str);
var byteNew = MD5.HashData(byteOld);
StringBuilder sb = new(32);
foreach (var b in byteNew)
2022-12-13 12:02:45 +00:00
{
sb.Append(b.ToString("x2"));
2022-12-13 12:02:45 +00:00
}
2024-11-01 06:54:23 +00:00
return sb.ToString();
2022-12-13 12:02:45 +00:00
}
catch (Exception ex)
2023-04-06 03:40:28 +00:00
{
Logging.SaveLog(_tag, ex);
return string.Empty;
2023-04-06 03:40:28 +00:00
}
}
2023-04-06 03:40:28 +00:00
public static string GetFileHash(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
return string.Empty;
}
if (!File.Exists(filePath))
2019-10-11 06:15:20 +00:00
{
return string.Empty;
2019-10-11 06:15:20 +00:00
}
try
2019-10-11 06:15:20 +00:00
{
using var md5 = MD5.Create();
using var stream = File.OpenRead(filePath);
var hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
2019-10-11 06:15:20 +00:00
}
catch (Exception ex)
2021-03-21 02:09:39 +00:00
{
Logging.SaveLog(_tag, ex);
return string.Empty;
}
}
2024-11-01 06:54:23 +00:00
/// <summary>
/// idn to idc
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string GetPunycode(string url)
{
if (url.IsNullOrEmpty())
{
return url;
2021-03-21 02:09:39 +00:00
}
try
2024-10-24 09:09:07 +00:00
{
Uri uri = new(url);
if (uri.Host == uri.IdnHost || uri.Host == $"[{uri.IdnHost}]")
2024-10-24 09:09:07 +00:00
{
return url;
2024-10-24 09:09:07 +00:00
}
else
2024-10-24 09:09:07 +00:00
{
return url.Replace(uri.Host, uri.IdnHost);
2024-10-24 09:09:07 +00:00
}
}
catch
2024-10-24 09:09:07 +00:00
{
return url;
2024-10-24 09:09:07 +00:00
}
}
2024-10-24 09:09:07 +00:00
public static bool IsBase64String(string? plainText)
{
if (plainText.IsNullOrEmpty())
return false;
var buffer = new Span<byte>(new byte[plainText.Length]);
return Convert.TryFromBase64String(plainText, buffer, out var _);
}
2019-10-11 06:15:20 +00:00
public static string Convert2Comma(string text)
{
if (text.IsNullOrEmpty())
2022-01-12 13:05:03 +00:00
{
return text;
}
return text.Replace("", ",").Replace(Environment.NewLine, ",");
}
2025-07-20 06:16:19 +00:00
public static List<string> GetEnumNames<TEnum>() where TEnum : Enum
{
return Enum.GetValues(typeof(TEnum))
.Cast<TEnum>()
.Select(e => e.ToString())
.ToList();
}
2025-09-12 08:28:31 +00:00
public static Dictionary<string, List<string>> ParseHostsToDictionary(string hostsContent)
{
var userHostsMap = hostsContent
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Trim())
// skip full-line comments
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
// strip inline comments (truncate at '#')
.Select(line =>
{
var index = line.IndexOf('#');
return index >= 0 ? line.Substring(0, index).Trim() : line;
})
// ensure line still contains valid parts
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
.Where(parts => parts.Length >= 2)
.GroupBy(parts => parts[0])
.ToDictionary(
group => group.Key,
group => group.SelectMany(parts => parts.Skip(1)).ToList()
);
return userHostsMap;
}
#endregion
#region
2024-11-01 06:54:23 +00:00
/// <summary>
/// Determine if the input is a number
/// </summary>
/// <param name="oText"></param>
/// <returns></returns>
public static bool IsNumeric(string oText)
{
return oText.All(char.IsNumber);
}
/// <summary>
/// Validate if the domain address is valid
/// </summary>
/// <param name="domain"></param>
public static bool IsDomain(string? domain)
{
if (domain.IsNullOrEmpty())
{
2024-10-14 02:42:05 +00:00
return false;
2022-01-12 13:05:03 +00:00
}
2023-04-14 12:49:36 +00:00
return Uri.CheckHostName(domain) == UriHostNameType.Dns;
}
2024-02-08 06:01:33 +00:00
public static bool IsIpv6(string ip)
{
if (IPAddress.TryParse(ip, out var address))
{
return address.AddressFamily switch
2024-02-08 06:01:33 +00:00
{
AddressFamily.InterNetwork => false,
AddressFamily.InterNetworkV6 => true,
_ => false,
};
2024-02-08 06:01:33 +00:00
}
return false;
}
2019-10-11 06:15:20 +00:00
public static Uri? TryUri(string url)
{
try
{
return new Uri(url);
}
catch (UriFormatException)
2019-10-11 06:15:20 +00:00
{
return null;
}
}
2024-11-01 06:54:23 +00:00
public static bool IsPrivateNetwork(string ip)
{
if (IPAddress.TryParse(ip, out var address))
{
// Loopback address check (127.0.0.1 for IPv4, ::1 for IPv6)
if (IPAddress.IsLoopback(address))
return true;
var ipBytes = address.GetAddressBytes();
if (address.AddressFamily == AddressFamily.InterNetwork)
{
// IPv4 private address check
if (ipBytes[0] == 10)
return true;
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
return true;
if (ipBytes[0] == 192 && ipBytes[1] == 168)
return true;
}
else if (address.AddressFamily == AddressFamily.InterNetworkV6)
{
// IPv6 private address check
// Link-local address fe80::/10
if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80)
return true;
2025-08-10 01:17:15 +00:00
// Unique local address fc00::/7 (typically fd00::/8)
if ((ipBytes[0] & 0xfe) == 0xfc)
return true;
2025-08-10 01:17:15 +00:00
// Private portion in IPv4-mapped addresses ::ffff:0:0/96
if (address.IsIPv4MappedToIPv6)
{
var ipv4Bytes = ipBytes.Skip(12).ToArray();
if (ipv4Bytes[0] == 10)
return true;
if (ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31)
return true;
if (ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168)
return true;
}
}
2019-10-11 06:15:20 +00:00
}
return false;
}
#endregion
#region
private static bool PortInUse(int port)
{
try
2024-08-29 07:19:03 +00:00
{
List<IPEndPoint> lstIpEndPoints = new();
List<TcpConnectionInformation> lstTcpConns = new();
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
if (lstIpEndPoints?.FindIndex(it => it.Port == port) >= 0)
2024-08-29 07:19:03 +00:00
{
return true;
2024-08-29 07:19:03 +00:00
}
if (lstTcpConns?.FindIndex(it => it.LocalEndPoint.Port == port) >= 0)
2024-08-29 07:19:03 +00:00
{
return true;
2024-08-29 07:19:03 +00:00
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return false;
}
public static int GetFreePort(int defaultPort = 0)
{
try
2019-10-11 06:15:20 +00:00
{
if (!(defaultPort == 0 || Utils.PortInUse(defaultPort)))
2019-10-11 06:15:20 +00:00
{
return defaultPort;
2019-10-11 06:15:20 +00:00
}
2024-11-01 06:54:23 +00:00
TcpListener l = new(IPAddress.Loopback, 0);
l.Start();
var port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
catch
{
}
return 59090;
}
#endregion
#region
public static bool UpgradeAppExists(out string upgradeFileName)
{
upgradeFileName = Path.Combine(GetBaseDirectory(), GetExeName("AmazTool"));
return File.Exists(upgradeFileName);
}
/// <summary>
/// Get version
/// </summary>
/// <returns></returns>
public static string GetVersion(bool blFull = true)
{
try
{
return blFull
? $"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture}"
: $"{Global.AppName}/{GetVersionInfo()}";
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
2019-10-11 06:15:20 +00:00
}
return Global.AppName;
}
public static string GetVersionInfo()
{
try
2022-03-17 11:07:06 +00:00
{
return Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString(3) ?? "0.0";
2022-03-17 11:07:06 +00:00
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
return "0.0";
}
}
2023-04-14 12:49:36 +00:00
public static string GetRuntimeInfo()
{
return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion}";
}
/// <summary>
/// GUID
/// </summary>
/// <returns></returns>
public static string GetGuid(bool full = true)
{
try
{
if (full)
{
return Guid.NewGuid().ToString("D");
}
else
{
return BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0).ToString();
}
}
catch (Exception ex)
2024-10-08 12:45:56 +00:00
{
Logging.SaveLog(_tag, ex);
2024-10-08 12:45:56 +00:00
}
return string.Empty;
}
public static bool IsGuidByParse(string strSrc)
{
return Guid.TryParse(strSrc, out _);
}
public static Dictionary<string, string> GetSystemHosts()
{
var systemHosts = new Dictionary<string, string>();
var hostFile = @"C:\Windows\System32\drivers\etc\hosts";
try
2024-10-08 12:45:56 +00:00
{
if (File.Exists(hostFile))
2024-10-08 12:45:56 +00:00
{
var hosts = File.ReadAllText(hostFile).Replace("\r", "");
var hostsList = hosts.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
2024-11-01 06:54:23 +00:00
foreach (var host in hostsList)
2024-10-08 12:45:56 +00:00
{
if (host.StartsWith("#"))
continue;
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length < 2)
continue;
systemHosts.Add(hostItem[1], hostItem[0]);
2024-10-08 12:45:56 +00:00
}
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
2024-10-08 12:45:56 +00:00
}
return systemHosts;
}
2019-10-11 06:15:20 +00:00
public static async Task<string?> GetCliWrapOutput(string filePath, string? arg)
{
return await GetCliWrapOutput(filePath, arg != null ? new List<string>() { arg } : null);
}
2019-10-11 06:15:20 +00:00
public static async Task<string?> GetCliWrapOutput(string filePath, IEnumerable<string>? args)
{
try
{
var cmd = Cli.Wrap(filePath);
if (args != null)
{
if (args.Count() == 1)
{
cmd = cmd.WithArguments(args.First());
}
else
{
cmd = cmd.WithArguments(args);
}
}
var result = await cmd.ExecuteBufferedAsync();
if (result.IsSuccess)
{
return result.StandardOutput ?? "";
}
2024-11-01 06:54:23 +00:00
Logging.SaveLog(result.ToString() ?? "");
}
catch (Exception ex)
{
Logging.SaveLog("GetCliWrapOutput", ex);
}
return null;
}
#endregion
#region TempPath
public static bool HasWritePermission()
{
try
2019-10-11 06:15:20 +00:00
{
var basePath = GetBaseDirectory();
//When this file exists, it is equivalent to having no permission to read and write
if (File.Exists(Path.Combine(basePath, "NotStoreConfigHere.txt")))
2019-10-11 06:15:20 +00:00
{
return false;
2019-10-11 06:15:20 +00:00
}
2024-11-01 06:54:23 +00:00
//Check if it is installed by Windows WinGet
if (IsWindows() && basePath.Contains("Users") && basePath.Contains("WinGet"))
2022-03-20 12:40:07 +00:00
{
return false;
2022-03-20 12:40:07 +00:00
}
2019-10-11 06:15:20 +00:00
var tempPath = Path.Combine(basePath, "guiTemps");
2024-10-14 02:42:05 +00:00
if (!Directory.Exists(tempPath))
2022-03-20 12:40:07 +00:00
{
2024-10-14 02:42:05 +00:00
Directory.CreateDirectory(tempPath);
2022-03-20 12:40:07 +00:00
}
var fileName = Path.Combine(tempPath, GetGuid());
File.Create(fileName).Close();
File.Delete(fileName);
2022-03-20 12:40:07 +00:00
}
catch (Exception)
2022-03-20 12:40:07 +00:00
{
return false;
}
2024-11-01 06:54:23 +00:00
return true;
}
public static string GetPath(string fileName)
{
var startupPath = StartupPath();
if (fileName.IsNullOrEmpty())
{
return startupPath;
2022-03-20 12:40:07 +00:00
}
2023-04-14 12:49:36 +00:00
return Path.Combine(startupPath, fileName);
}
public static string GetBaseDirectory(string fileName = "")
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
}
public static string GetExePath()
{
return Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
}
public static string StartupPath()
{
if (Environment.GetEnvironmentVariable(Global.LocalAppData) == "1")
2023-01-01 11:42:01 +00:00
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "v2rayN");
}
2024-11-01 06:54:23 +00:00
return GetBaseDirectory();
}
2024-11-01 06:54:23 +00:00
public static string GetTempPath(string filename = "")
{
var tempPath = Path.Combine(StartupPath(), "guiTemps");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
if (filename.IsNullOrEmpty())
2023-01-01 11:42:01 +00:00
{
return tempPath;
}
else
{
return Path.Combine(tempPath, filename);
}
}
2024-11-01 06:54:23 +00:00
public static string GetBackupPath(string filename)
{
var tempPath = Path.Combine(StartupPath(), "guiBackups");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
return Path.Combine(tempPath, filename);
}
public static string GetConfigPath(string filename = "")
{
var tempPath = Path.Combine(StartupPath(), "guiConfigs");
if (!Directory.Exists(tempPath))
2023-02-04 04:50:38 +00:00
{
Directory.CreateDirectory(tempPath);
}
if (filename.IsNullOrEmpty())
{
return tempPath;
}
else
{
return Path.Combine(tempPath, filename);
}
}
public static string GetBinPath(string filename, string? coreType = null)
{
var tempPath = Path.Combine(StartupPath(), "bin");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
if (coreType != null)
{
tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
if (!Directory.Exists(tempPath))
2023-02-04 04:50:38 +00:00
{
2024-10-14 02:42:05 +00:00
Directory.CreateDirectory(tempPath);
2023-02-04 04:50:38 +00:00
}
}
2022-03-20 12:40:07 +00:00
if (filename.IsNullOrEmpty())
{
return tempPath;
}
else
{
return Path.Combine(tempPath, filename);
}
}
public static string GetLogPath(string filename = "")
{
var tempPath = Path.Combine(StartupPath(), "guiLogs");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
if (filename.IsNullOrEmpty())
{
return tempPath;
2024-10-08 09:40:25 +00:00
}
else
{
return Path.Combine(tempPath, filename);
}
}
2024-10-08 09:40:25 +00:00
public static string GetFontsPath(string filename = "")
{
var tempPath = Path.Combine(StartupPath(), "guiFonts");
if (!Directory.Exists(tempPath))
2024-10-08 09:40:25 +00:00
{
Directory.CreateDirectory(tempPath);
}
if (filename.IsNullOrEmpty())
{
return tempPath;
}
else
{
return Path.Combine(tempPath, filename);
}
}
public static string GetBinConfigPath(string filename = "")
{
var tempPath = Path.Combine(StartupPath(), "binConfigs");
if (!Directory.Exists(tempPath))
2024-10-27 06:59:06 +00:00
{
Directory.CreateDirectory(tempPath);
2024-10-27 06:59:06 +00:00
}
if (filename.IsNullOrEmpty())
2024-11-01 06:54:23 +00:00
{
return tempPath;
2024-11-01 06:54:23 +00:00
}
else
{
return Path.Combine(tempPath, filename);
}
}
#endregion TempPath
#region Platform
public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
2024-11-01 06:54:23 +00:00
public static bool IsOSX() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
public static bool IsNonWindows() => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static string GetExeName(string name)
{
return IsWindows() ? $"{name}.exe" : name;
2019-10-11 06:15:20 +00:00
}
public static bool IsAdministrator()
{
if (IsWindows())
{
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
}
return false;
}
public static bool IsPackagedInstall()
{
try
{
if (IsWindows() || IsOSX())
{
return false;
}
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPIMAGE")))
{
return true;
}
var exePath = GetExePath();
var baseDir = string.IsNullOrEmpty(exePath) ? StartupPath() : Path.GetDirectoryName(exePath) ?? "";
var p = baseDir.Replace('\\', '/');
if (string.IsNullOrEmpty(p))
{
return false;
}
if (p.Contains("/.mount_", StringComparison.Ordinal))
{
return true;
}
if (p.StartsWith("/opt/v2rayN", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (p.StartsWith("/usr/lib/v2rayN", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (p.StartsWith("/usr/share/v2rayN", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
catch
{
}
return false;
}
private static async Task<string?> GetLinuxUserId()
{
var arg = new List<string>() { "-c", "id -u" };
return await GetCliWrapOutput(Global.LinuxBash, arg);
}
public static async Task<string?> SetLinuxChmod(string? fileName)
{
if (fileName.IsNullOrEmpty())
{
return null;
}
if (SetUnixFileMode(fileName))
{
Logging.SaveLog($"Successfully set the file execution permission, {fileName}");
return string.Empty;
}
if (fileName.Contains(' '))
{
fileName = fileName.AppendQuotes();
}
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
return await GetCliWrapOutput(Global.LinuxBash, arg);
}
public static bool SetUnixFileMode(string? fileName)
{
try
{
if (fileName.IsNullOrEmpty())
{
return false;
}
if (File.Exists(fileName))
{
var currentMode = File.GetUnixFileMode(fileName);
File.SetUnixFileMode(fileName, currentMode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute);
return true;
}
}
catch (Exception ex)
{
Logging.SaveLog("SetUnixFileMode", ex);
}
return false;
}
public static async Task<string?> GetLinuxFontFamily(string lang)
{
// var arg = new List<string>() { "-c", $"fc-list :lang={lang} family" };
var arg = new List<string>() { "-c", $"fc-list : family" };
return await GetCliWrapOutput(Global.LinuxBash, arg);
}
public static string? GetHomePath()
{
return IsWindows()
? Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%")
: Environment.GetEnvironmentVariable("HOME");
}
#endregion Platform
2025-01-30 09:10:05 +00:00
}