| 
									
										
										
										
											2024-10-08 09:40:25 +00:00
										 |  |  |  | using System.Collections.Specialized; | 
					
						
							| 
									
										
										
										
											2024-10-06 02:23:44 +00:00
										 |  |  |  | using System.Security.Principal; | 
					
						
							| 
									
										
										
										
											2025-01-30 09:10:05 +00:00
										 |  |  |  | using CliWrap; | 
					
						
							|  |  |  |  | using CliWrap.Buffered; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  | namespace ServiceLib.Common; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | public class Utils | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     private static readonly string _tag = "Utils"; | 
					
						
							| 
									
										
										
										
											2025-01-03 07:02:31 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     #region 转换函数 | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return string.Empty; | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:06 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         var separator = wrap ? "," + Environment.NewLine : ","; | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:06 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         try | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return string.Join(separator, lst); | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							|  |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// Comma-separated string | 
					
						
							|  |  |  |  |     /// </summary> | 
					
						
							|  |  |  |  |     /// <param name="str"></param> | 
					
						
							|  |  |  |  |     /// <returns></returns> | 
					
						
							|  |  |  |  |     public static List<string>? String2List(string? str) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (string.IsNullOrWhiteSpace(str)) | 
					
						
							| 
									
										
										
										
											2022-04-01 05:21:22 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2022-04-01 05:21:22 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							|  |  |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// Base64 Encode | 
					
						
							|  |  |  |  |     /// </summary> | 
					
						
							|  |  |  |  |     /// <param name="plainText"></param> | 
					
						
							| 
									
										
										
										
											2025-10-03 06:13:03 +00:00
										 |  |  |  |     /// <param name="removePadding"></param> | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     /// <returns></returns> | 
					
						
							| 
									
										
										
										
											2025-10-03 06:13:03 +00:00
										 |  |  |  |     public static string Base64Encode(string plainText, bool removePadding = false) | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2022-03-13 02:41:04 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var plainTextBytes = Encoding.UTF8.GetBytes(plainText); | 
					
						
							| 
									
										
										
										
											2025-10-03 06:13:03 +00:00
										 |  |  |  |             var base64 = Convert.ToBase64String(plainTextBytes); | 
					
						
							|  |  |  |  |             if (removePadding) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 base64 = base64.TrimEnd('='); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             return base64; | 
					
						
							| 
									
										
										
										
											2022-03-13 02:41:04 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             if (plainText.IsNullOrEmpty()) | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:06 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-10-03 06:13:03 +00:00
										 |  |  |  |                 return string.Empty; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:06 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             plainText = plainText.Trim() | 
					
						
							|  |  |  |  |                 .Replace(Environment.NewLine, "") | 
					
						
							|  |  |  |  |                 .Replace("\n", "") | 
					
						
							|  |  |  |  |                 .Replace("\r", "") | 
					
						
							|  |  |  |  |                 .Replace('_', '/') | 
					
						
							|  |  |  |  |                 .Replace('-', '+') | 
					
						
							|  |  |  |  |                 .Replace(" ", ""); | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:06 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             if (plainText.Length % 4 > 0) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 plainText = plainText.PadRight(plainText.Length + 4 - (plainText.Length % 4), '='); | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2021-01-06 11:54:15 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-14 12:49:36 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string ToString(object? obj) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2021-01-06 11:54:15 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return obj?.ToString() ?? string.Empty; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         catch | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2024-01-16 03:05:02 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-01-16 03:05:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string HumanFy(long amount) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (amount <= 0) | 
					
						
							| 
									
										
										
										
											2024-01-16 03:05:02 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return $"{amount:f1} B"; | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-01-16 03:05:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         string[] units = ["KB", "MB", "GB", "TB", "PB"]; | 
					
						
							|  |  |  |  |         var unitIndex = 0; | 
					
						
							|  |  |  |  |         double size = amount; | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return $"{size:f1} {units[unitIndex]}"; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-01-16 03:05:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         var parts = query[1..].Split('&', StringSplitOptions.RemoveEmptyEntries); | 
					
						
							|  |  |  |  |         foreach (var part in parts) | 
					
						
							| 
									
										
										
										
											2022-05-12 00:52:40 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var keyValue = part.Split('='); | 
					
						
							|  |  |  |  |             if (keyValue.Length != 2) | 
					
						
							| 
									
										
										
										
											2022-05-12 00:52:40 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2025-03-17 03:05:04 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var key = Uri.UnescapeDataString(keyValue.First()); | 
					
						
							|  |  |  |  |             var val = Uri.UnescapeDataString(keyValue.Last()); | 
					
						
							| 
									
										
										
										
											2025-03-17 03:05:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             if (result[key] is null) | 
					
						
							| 
									
										
										
										
											2025-03-17 03:05:04 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 result.Add(key, val); | 
					
						
							| 
									
										
										
										
											2025-03-17 03:05:04 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return result; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-03-17 03:05:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2022-12-13 12:02:45 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 sb.Append(b.ToString("x2")); | 
					
						
							| 
									
										
										
										
											2022-12-13 12:02:45 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return sb.ToString(); | 
					
						
							| 
									
										
										
										
											2022-12-13 12:02:45 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2023-04-06 03:40:28 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							|  |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2023-04-06 03:40:28 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-06 03:40:28 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string GetFileHash(string filePath) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (string.IsNullOrEmpty(filePath)) | 
					
						
							| 
									
										
										
										
											2023-04-28 02:22:55 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2023-04-28 02:22:55 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (!File.Exists(filePath)) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2021-03-21 02:09:39 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							|  |  |  |  |             return string.Empty; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Uri uri = new(url); | 
					
						
							|  |  |  |  |             if (uri.Host == uri.IdnHost || uri.Host == $"[{uri.IdnHost}]") | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return url; | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             else | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return url.Replace(uri.Host, uri.IdnHost); | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return url; | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-24 09:09:07 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string Convert2Comma(string text) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (text.IsNullOrEmpty()) | 
					
						
							| 
									
										
										
										
											2022-01-12 13:05:03 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return text; | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return text.Replace(",", ",").Replace(Environment.NewLine, ","); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-21 09:28:48 +00:00
										 |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// Parse a possibly non-standard URL into scheme, domain, port, and path. | 
					
						
							|  |  |  |  |     /// If parsing fails, the entire input is returned as domain, and others are empty or zero. | 
					
						
							|  |  |  |  |     /// </summary> | 
					
						
							|  |  |  |  |     /// <param name="url">Input URL or string</param> | 
					
						
							|  |  |  |  |     /// <returns>(domain, scheme, port, path)</returns> | 
					
						
							|  |  |  |  |     public static (string domain, string scheme, int port, string path) ParseUrl(string url) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (string.IsNullOrWhiteSpace(url)) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return ("", "", 0, ""); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 1. First, try to parse using the standard Uri class. | 
					
						
							|  |  |  |  |         if (Uri.TryCreate(url, UriKind.Absolute, out var uri) && !string.IsNullOrEmpty(uri.Host)) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             var scheme = uri.Scheme; | 
					
						
							|  |  |  |  |             var domain = uri.Host; | 
					
						
							|  |  |  |  |             var port = uri.IsDefaultPort ? 0 : uri.Port; | 
					
						
							|  |  |  |  |             var path = uri.PathAndQuery; | 
					
						
							|  |  |  |  |             return (domain, scheme, port, path); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 2. Try to handle more general cases with a regular expression, including non-standard schemes. | 
					
						
							|  |  |  |  |         // This regex captures the scheme (optional), authority (host+port), and path (optional). | 
					
						
							|  |  |  |  |         var match = Regex.Match(url, @"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):/{2,})?([^/?#]+)([^?#]*)?.*$"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (match.Success) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             var scheme = match.Groups[1].Value; | 
					
						
							|  |  |  |  |             var authority = match.Groups[2].Value; | 
					
						
							|  |  |  |  |             var path = match.Groups[3].Value; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // Remove userinfo from the authority part. | 
					
						
							|  |  |  |  |             var atIndex = authority.LastIndexOf('@'); | 
					
						
							|  |  |  |  |             if (atIndex > 0) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 authority = authority.Substring(atIndex + 1); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             var (domain, port) = ParseAuthority(authority); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // If the parsed domain is empty, it means the authority part is malformed, so trigger the fallback. | 
					
						
							|  |  |  |  |             if (!string.IsNullOrEmpty(domain)) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return (domain, scheme, port, path); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 3. If all of the above fails, execute the final fallback strategy. | 
					
						
							|  |  |  |  |         return (url, "", 0, ""); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// Helper function to parse domain and port from the authority part, with correct handling for IPv6. | 
					
						
							|  |  |  |  |     /// </summary> | 
					
						
							|  |  |  |  |     private static (string domain, int port) ParseAuthority(string authority) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (string.IsNullOrEmpty(authority)) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return ("", 0); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         var port = 0; | 
					
						
							|  |  |  |  |         var domain = authority; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // Handle IPv6 addresses, e.g., "[2001:db8::1]:443" | 
					
						
							|  |  |  |  |         if (authority.StartsWith("[") && authority.Contains("]")) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             int closingBracketIndex = authority.LastIndexOf(']'); | 
					
						
							|  |  |  |  |             if (closingBracketIndex < authority.Length - 1 && authority[closingBracketIndex + 1] == ':') | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 // Port exists | 
					
						
							|  |  |  |  |                 var portStr = authority.Substring(closingBracketIndex + 2); | 
					
						
							|  |  |  |  |                 if (int.TryParse(portStr, out var portNum)) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     port = portNum; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 domain = authority.Substring(0, closingBracketIndex + 1); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             else | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 // No port | 
					
						
							|  |  |  |  |                 domain = authority; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else // Handle IPv4 or domain names | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             var lastColonIndex = authority.LastIndexOf(':'); | 
					
						
							|  |  |  |  |             // Ensure there are digits after the colon and that this colon is not part of an IPv6 address. | 
					
						
							|  |  |  |  |             if (lastColonIndex > 0 && lastColonIndex < authority.Length - 1 && authority.Substring(lastColonIndex + 1).All(char.IsDigit)) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 var portStr = authority.Substring(lastColonIndex + 1); | 
					
						
							|  |  |  |  |                 if (int.TryParse(portStr, out var portNum)) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     port = portNum; | 
					
						
							|  |  |  |  |                     domain = authority.Substring(0, lastColonIndex); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return (domain, port); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     #endregion 转换函数 | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     #region 数据检查 | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return Uri.CheckHostName(domain) == UriHostNameType.Dns; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-02-08 06:01:33 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 AddressFamily.InterNetwork => false, | 
					
						
							|  |  |  |  |                 AddressFamily.InterNetworkV6 => true, | 
					
						
							|  |  |  |  |                 _ => false, | 
					
						
							|  |  |  |  |             }; | 
					
						
							| 
									
										
										
										
											2024-02-08 06:01:33 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static Uri? TryUri(string url) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2024-10-15 01:31:30 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return new Uri(url); | 
					
						
							| 
									
										
										
										
											2024-10-15 01:31:30 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (UriFormatException) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return null; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static bool IsPrivateNetwork(string ip) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (IPAddress.TryParse(ip, out var address)) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-07-29 11:18:13 +00:00
										 |  |  |  |             // Loopback address check (127.0.0.1 for IPv4, ::1 for IPv6) | 
					
						
							|  |  |  |  |             if (IPAddress.IsLoopback(address)) | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return true; | 
					
						
							| 
									
										
										
										
											2025-07-29 11:18:13 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-29 11:18:13 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-29 11:18:13 +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
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     #endregion 数据检查 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     #region 测速 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private static bool PortInUse(int port) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2024-08-29 07:19:03 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return true; | 
					
						
							| 
									
										
										
										
											2024-08-29 07:19:03 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (lstTcpConns?.FindIndex(it => it.LocalEndPoint.Port == port) >= 0) | 
					
						
							| 
									
										
										
										
											2024-08-29 07:19:03 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return true; | 
					
						
							| 
									
										
										
										
											2024-08-29 07:19:03 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2025-01-01 02:38:55 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							| 
									
										
										
										
											2025-01-01 02:38:55 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 02:15:32 +00:00
										 |  |  |  |     public static int GetFreePort(int defaultPort = 0) | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-08-10 02:15:32 +00:00
										 |  |  |  |             if (!(defaultPort == 0 || Utils.PortInUse(defaultPort))) | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return defaultPort; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return Global.AppName; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public static string GetVersionInfo() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2022-03-17 11:07:06 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString(3) ?? "0.0"; | 
					
						
							| 
									
										
										
										
											2022-03-17 11:07:06 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							|  |  |  |  |             return "0.0"; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-14 12:49:36 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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 | 
					
						
							| 
									
										
										
										
											2024-01-28 11:53:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             if (full) | 
					
						
							| 
									
										
										
										
											2024-01-28 11:53:20 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return Guid.NewGuid().ToString("D"); | 
					
						
							| 
									
										
										
										
											2024-01-28 11:53:20 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             else | 
					
						
							| 
									
										
										
										
											2024-01-28 11:53:20 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0).ToString(); | 
					
						
							| 
									
										
										
										
											2024-01-28 11:53:20 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             if (File.Exists(hostFile)) | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 foreach (var host in hostsList) | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                     if (host.StartsWith("#")) | 
					
						
							|  |  |  |  |                         continue; | 
					
						
							|  |  |  |  |                     var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); | 
					
						
							| 
									
										
										
										
											2025-09-08 10:02:44 +00:00
										 |  |  |  |                     if (hostItem.Length < 2) | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                         continue; | 
					
						
							| 
									
										
										
										
											2025-09-08 10:02:44 +00:00
										 |  |  |  |                     systemHosts.Add(hostItem[1], hostItem[0]); | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |         catch (Exception ex) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Logging.SaveLog(_tag, ex); | 
					
						
							| 
									
										
										
										
											2024-10-08 12:45:56 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return systemHosts; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static async Task<string?> GetCliWrapOutput(string filePath, IEnumerable<string>? args) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2024-12-18 02:27:58 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var cmd = Cli.Wrap(filePath); | 
					
						
							|  |  |  |  |             if (args != null) | 
					
						
							| 
									
										
										
										
											2024-12-18 02:27:58 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 if (args.Count() == 1) | 
					
						
							| 
									
										
										
										
											2024-12-30 10:16:07 +00:00
										 |  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                     cmd = cmd.WithArguments(args.First()); | 
					
						
							| 
									
										
										
										
											2024-12-30 10:16:07 +00:00
										 |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 else | 
					
						
							| 
									
										
										
										
											2024-12-18 02:27:58 +00:00
										 |  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                     cmd = cmd.WithArguments(args); | 
					
						
							| 
									
										
										
										
											2024-12-18 02:27:58 +00:00
										 |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var result = await cmd.ExecuteBufferedAsync(); | 
					
						
							|  |  |  |  |             if (result.IsSuccess) | 
					
						
							| 
									
										
										
										
											2024-01-31 01:56:47 +00:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |                 return result.StandardOutput ?? ""; | 
					
						
							| 
									
										
										
										
											2024-01-31 01:56:47 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog(result.ToString() ?? ""); | 
					
						
							| 
									
										
										
										
											2024-01-31 01:56:47 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception ex) | 
					
						
							| 
									
										
										
										
											2025-01-18 08:58:44 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Logging.SaveLog("GetCliWrapOutput", ex); | 
					
						
							| 
									
										
										
										
											2025-01-18 08:58:44 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return null; | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-01-31 01:56:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     #endregion 杂项 | 
					
						
							| 
									
										
										
										
											2024-12-18 02:27:58 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     #region TempPath | 
					
						
							| 
									
										
										
										
											2024-01-31 01:56:47 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static bool HasWritePermission() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return false; | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |                 return false; | 
					
						
							| 
									
										
										
										
											2022-03-20 12:40:07 +00:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-10-11 06:15:20 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             var fileName = Path.Combine(tempPath, GetGuid()); | 
					
						
							|  |  |  |  |             File.Create(fileName).Close(); | 
					
						
							|  |  |  |  |             File.Delete(fileName); | 
					
						
							| 
									
										
										
										
											2022-03-20 12:40:07 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         catch (Exception) | 
					
						
							| 
									
										
										
										
											2022-03-20 12:40:07 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "v2rayN"); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         return GetBaseDirectory(); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (filename.IsNullOrEmpty()) | 
					
						
							| 
									
										
										
										
											2023-01-01 11:42:01 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return tempPath; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return Path.Combine(tempPath, filename); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Directory.CreateDirectory(tempPath); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         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); | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (coreType != null) | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             tempPath = Path.Combine(tempPath, coreType.ToLower().ToString()); | 
					
						
							| 
									
										
										
										
											2025-02-13 11:46:51 +00:00
										 |  |  |  |             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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (filename.IsNullOrEmpty()) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return tempPath; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return Path.Combine(tempPath, filename); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-12-19 03:24:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string GetLogPath(string filename = "") | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         var tempPath = Path.Combine(StartupPath(), "guiLogs"); | 
					
						
							|  |  |  |  |         if (!Directory.Exists(tempPath)) | 
					
						
							| 
									
										
										
										
											2024-10-06 02:23:44 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Directory.CreateDirectory(tempPath); | 
					
						
							| 
									
										
										
										
											2024-10-06 02:23:44 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (filename.IsNullOrEmpty()) | 
					
						
							| 
									
										
										
										
											2024-10-06 02:23:44 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return tempPath; | 
					
						
							| 
									
										
										
										
											2024-10-08 09:40:25 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         else | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return Path.Combine(tempPath, filename); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-08 09:40:25 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +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
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Directory.CreateDirectory(tempPath); | 
					
						
							| 
									
										
										
										
											2024-10-06 02:23:44 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (filename.IsNullOrEmpty()) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return tempPath; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         else | 
					
						
							| 
									
										
										
										
											2024-10-22 12:08:33 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return Path.Combine(tempPath, filename); | 
					
						
							| 
									
										
										
										
											2024-10-22 12:08:33 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-22 12:08:33 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     public static string GetBinConfigPath(string filename = "") | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         var tempPath = Path.Combine(StartupPath(), "binConfigs"); | 
					
						
							|  |  |  |  |         if (!Directory.Exists(tempPath)) | 
					
						
							| 
									
										
										
										
											2024-10-27 06:59:06 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             Directory.CreateDirectory(tempPath); | 
					
						
							| 
									
										
										
										
											2024-10-27 06:59:06 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (filename.IsNullOrEmpty()) | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return tempPath; | 
					
						
							| 
									
										
										
										
											2024-11-01 06:54:23 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44: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
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     public static bool IsAdministrator() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (IsWindows()) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-12 08:24:59 +00:00
										 |  |  |  |     public static bool IsPackagedInstall() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (IsWindows() || IsOSX()) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return false; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             var exePath = GetExePath(); | 
					
						
							|  |  |  |  |             var baseDir = string.IsNullOrEmpty(exePath) ? StartupPath() : Path.GetDirectoryName(exePath) ?? ""; | 
					
						
							|  |  |  |  |             var p = baseDir.Replace('\\', '/'); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (string.IsNullOrEmpty(p)) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return false; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             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; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     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()) | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             return null; | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |         if (SetUnixFileMode(fileName)) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Logging.SaveLog($"Successfully set the file execution permission, {fileName}"); | 
					
						
							| 
									
										
										
										
											2025-10-03 06:13:03 +00:00
										 |  |  |  |             return string.Empty; | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         if (fileName.Contains(' ')) | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |             fileName = fileName.AppendQuotes(); | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |         var arg = new List<string>() { "-c", $"chmod +x {fileName}" }; | 
					
						
							|  |  |  |  |         return await GetCliWrapOutput(Global.LinuxBash, arg); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-15 04:33:21 +00:00
										 |  |  |  |     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; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-02 03:44:23 +00:00
										 |  |  |  |     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
										 |  |  |  | } |