init commit
This commit is contained in:
280
20220330_Vote/Ewide.Core/Util/CodeHelper.cs
Normal file
280
20220330_Vote/Ewide.Core/Util/CodeHelper.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
using Aliyun.Acs.Core;
|
||||
using Aliyun.Acs.Core.Exceptions;
|
||||
using Aliyun.Acs.Core.Profile;
|
||||
using Furion;
|
||||
using Furion.DatabaseAccessor;
|
||||
using Furion.FriendlyException;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public class CodeHelper
|
||||
{
|
||||
private readonly IMemoryCache _IMemoryCache;
|
||||
private readonly IRepository<SysUser> _sysUserRep; // 用户表仓储
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
public CodeHelper(
|
||||
IMemoryCache IMemoryCache,
|
||||
IRepository<SysUser> sysUserRep,
|
||||
IUserManager userManager
|
||||
){
|
||||
_IMemoryCache = IMemoryCache;
|
||||
_sysUserRep = sysUserRep;
|
||||
_userManager = userManager;
|
||||
}
|
||||
public static string Aliyun_AccessKey = App.Configuration["SmsHelper:Aliyun_AccessKey"];
|
||||
public static string Aliyun_AccessSecret = App.Configuration["SmsHelper:Aliyun_AccessSecret"];
|
||||
public static string Aliyun_Smscode_SignName = App.Configuration["SmsHelper:Aliyun_Smscode_SignName"];
|
||||
public static string Aliyun_Smscode_TemplateCode = App.Configuration["SmsHelper:Aliyun_Smscode_TemplateCode"];
|
||||
|
||||
/// <summary>
|
||||
/// 发送验证码间隔时间(秒)
|
||||
/// </summary>
|
||||
protected static int code_Countdown = 60;
|
||||
|
||||
/// <summary>
|
||||
/// 验证code
|
||||
/// </summary>
|
||||
protected static string Orgcode_Key = "ewide_Orgcode";
|
||||
|
||||
///<summary>
|
||||
///邮箱Code
|
||||
/// </summary>
|
||||
protected static string mailcode_Key = "ewide_mailcode";
|
||||
|
||||
///<summary>
|
||||
///手机Code
|
||||
/// </summary>
|
||||
protected static string smscode_Key = "ewide_smscode";
|
||||
|
||||
/// <summary>
|
||||
/// 将code存入缓存
|
||||
/// </summary>
|
||||
/// <param name="way">验证方式</param>
|
||||
/// <param name="code">验证码</param>
|
||||
/// <param name="type">code的类型</param>
|
||||
public void Updatecode(string num, int code, string way)
|
||||
{
|
||||
|
||||
var ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||
_IMemoryCache.Set(
|
||||
way + "_" + num, // code的类型_手机或者邮箱号码
|
||||
code + "_" + (int)ts.TotalSeconds, // 1234567_TimeStamp
|
||||
DateTime.UtcNow.AddMinutes(5)// 5分钟过期
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否含有code
|
||||
/// </summary>
|
||||
/// <param name="way"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public bool Checkcode(string Target, int? code,string Key)
|
||||
{
|
||||
var cache = (string)_IMemoryCache.Get(Key + "_" + Target);// 获取匹配类型的code值
|
||||
if (string.IsNullOrEmpty(cache))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return code == cache.Split('_').Select(p => int.Parse(p)).First();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否含有code
|
||||
/// </summary>
|
||||
/// <param name="way"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public bool Checkhavecode(string num, string way)
|
||||
{
|
||||
var cache = (string)_IMemoryCache.Get(way + "_" + num);// 获取匹配类型的code值
|
||||
if (string.IsNullOrEmpty(cache))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除相应缓存
|
||||
/// </summary>
|
||||
/// <param name="way"></param>
|
||||
/// <param name="type"></param>
|
||||
public void removecode(string way, string num){
|
||||
_IMemoryCache.Remove(way + "_" + num);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// code60秒才可再次发送
|
||||
/// </summary>
|
||||
/// <param name="way">验证类型</param>
|
||||
/// <param name="num">值</param>
|
||||
/// <param name="coundown"></param>
|
||||
/// <returns></returns>
|
||||
public bool IscodeCountdown(string way, string num, int coundown = 60)
|
||||
{
|
||||
return GetSmscodeCountdown(way, num) < coundown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送验证码倒计时
|
||||
/// </summary>
|
||||
/// <param name="mobile"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSmscodeCountdown(string way,string num)
|
||||
{
|
||||
var cache = (string)_IMemoryCache.Get(way + "_" + num);
|
||||
if (String.IsNullOrEmpty(cache))
|
||||
{
|
||||
return code_Countdown;
|
||||
}
|
||||
var ts = cache.Split('_').Select(p => int.Parse(p)).Last();
|
||||
var nowTs = (int)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
|
||||
return nowTs - ts;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 发送手机验证码
|
||||
///</summary>
|
||||
public bool SendSmscode(string mobile, string way ,int length = 6)
|
||||
{
|
||||
if (!new Regex(@"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$").IsMatch(mobile))
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1011);
|
||||
}
|
||||
//if (IscodeCountdown(way, mobile, code_Countdown))
|
||||
//{
|
||||
// throw Oops.Oh(ErrorCode.D1023);
|
||||
|
||||
//}
|
||||
|
||||
IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", Aliyun_AccessKey, Aliyun_AccessSecret);
|
||||
DefaultAcsClient client = new DefaultAcsClient(profile);
|
||||
CommonRequest request = new CommonRequest
|
||||
{
|
||||
Method = Aliyun.Acs.Core.Http.MethodType.POST,
|
||||
Domain = "dysmsapi.aliyuncs.com",
|
||||
Version = "2017-05-25",
|
||||
Action = "SendSms"
|
||||
};
|
||||
request.AddQueryParameters("PhoneNumbers", mobile);
|
||||
request.AddQueryParameters("SignName", Aliyun_Smscode_SignName);
|
||||
request.AddQueryParameters("TemplateCode", Aliyun_Smscode_TemplateCode);
|
||||
|
||||
var minValue = Convert.ToInt32("1".PadRight(length, '0'));
|
||||
var maxValue = Convert.ToInt32("1".PadRight(length + 1, '0'));
|
||||
var code = new Random().Next(minValue, maxValue);
|
||||
var param = new { code };
|
||||
request.AddQueryParameters("TemplateParam", JsonConvert.SerializeObject(param));
|
||||
Updatecode(mobile, code,way);
|
||||
try
|
||||
{
|
||||
CommonResponse response = client.GetCommonResponse(request);
|
||||
var msg = System.Text.Encoding.UTF8.GetString(response.HttpResponse.Content);
|
||||
var result = JsonConvert.DeserializeObject(msg);
|
||||
var j = (JObject)result;
|
||||
if(!"OK".Equals(j["Code"].ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
throw Oops.Oh("请不要频繁发送");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (ServerException e)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1024);
|
||||
}catch(Exception e)
|
||||
{
|
||||
throw Oops.Oh("访问异常");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送邮箱
|
||||
/// </summary>
|
||||
/// <param name="mail"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public bool SendMail(string mail, string way,int length = 6)
|
||||
{
|
||||
if (!new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").IsMatch(mail))
|
||||
{
|
||||
throw Oops.Oh("格式不对");
|
||||
}
|
||||
if (IscodeCountdown(mail, way, code_Countdown))
|
||||
{
|
||||
throw Oops.Oh("60秒后才能再次发送");
|
||||
|
||||
}
|
||||
string account = App.Configuration["Mail:Account"];
|
||||
string passWord = App.Configuration["Mail:PassWord"];
|
||||
//var options = Options.Create(options: new MemoryCacheOptions());
|
||||
//IMemoryCache cache = new MemoryCache(options);
|
||||
SmtpClient smtpClient = new SmtpClient();
|
||||
smtpClient.EnableSsl = true;
|
||||
smtpClient.UseDefaultCredentials = false;
|
||||
smtpClient.Host = App.Configuration["Mail:Host"];
|
||||
smtpClient.Credentials = new System.Net.NetworkCredential(account, passWord);
|
||||
smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
|
||||
|
||||
MailMessage mailMessage = new MailMessage();
|
||||
MailAddress fromAddr = new MailAddress(account);
|
||||
mailMessage.From = fromAddr;
|
||||
mailMessage.To.Add(mail);
|
||||
mailMessage.Subject = App.Configuration["Mail:Subject"];
|
||||
mailMessage.BodyEncoding = Encoding.UTF8;
|
||||
mailMessage.IsBodyHtml = true;
|
||||
mailMessage.Priority = MailPriority.Low;
|
||||
var minValue = Convert.ToInt32("1".PadRight(length, '0'));
|
||||
var maxValue = Convert.ToInt32("1".PadRight(length + 1, '0'));
|
||||
var code = new Random().Next(minValue, maxValue);
|
||||
var param = new { code };
|
||||
Updatecode(mail, code, way);
|
||||
try
|
||||
{
|
||||
var Message = "邮箱验证码为:" + code.ToString();
|
||||
mailMessage.Body = Message;
|
||||
smtpClient.Send(mailMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.xg1100);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测是否重复
|
||||
/// </summary>
|
||||
/// <param name="Target"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> CheckRepeat(string Target)
|
||||
{
|
||||
var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
|
||||
var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
|
||||
if(new Regex(Regex_phone).IsMatch(Target)){
|
||||
var isExist = await _sysUserRep.DetachedEntities.AnyAsync(u => (u.Id != _userManager.UserId ) && (u.Account == Target || u.Phone == Target));
|
||||
if (isExist) throw Oops.Oh("手机号与他人账号或者手机号重复");
|
||||
}else if(new Regex(Regex_Email).IsMatch(Target))
|
||||
{
|
||||
var isExist3 = await _sysUserRep.DetachedEntities.AnyAsync(u => (u.Id != _userManager.UserId) && (u.Account == Target || u.Email == Target));
|
||||
if (isExist3) throw Oops.Oh("邮箱与他人账号或者邮箱重复");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
389
20220330_Vote/Ewide.Core/Util/MachineUtil.cs
Normal file
389
20220330_Vote/Ewide.Core/Util/MachineUtil.cs
Normal file
@@ -0,0 +1,389 @@
|
||||
using Furion.RemoteRequest.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取服务器信息
|
||||
/// </summary>
|
||||
public static class MachineUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取资源使用信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static dynamic GetMachineUseInfo()
|
||||
{
|
||||
var ramInfo = GetRamInfo();
|
||||
return new
|
||||
{
|
||||
RamRate = Math.Ceiling(100 * ramInfo.Used / ramInfo.Total), // 内存使用率
|
||||
CpuRate = Math.Ceiling(double.Parse(GetCPURate())), // cpu使用率
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取基本参数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<dynamic> GetMachineBaseInfo()
|
||||
{
|
||||
var assemblyName = typeof(Furion.App).Assembly.GetName();
|
||||
return new
|
||||
{
|
||||
WanIp = await GetWanIpFromPCOnline(), // 外网IP
|
||||
LanIp = Dns.GetHostAddresses(string.Empty).Last().ToString(), // 局域网IP
|
||||
IpMac = "",//networkInfo.Mac, // Mac地址
|
||||
HostName = Environment.MachineName, // HostName
|
||||
CurrentDirectory = Environment.CurrentDirectory, // 系统路径
|
||||
SystemOs = RuntimeInformation.OSDescription, // 系统名称
|
||||
OsArchitecture = Environment.OSVersion.Platform.ToString() + " " + RuntimeInformation.OSArchitecture.ToString(), // 系统架构
|
||||
ProcessorCount = Environment.ProcessorCount, // CPU核心数
|
||||
FrameworkDescription = RuntimeInformation.FrameworkDescription + " + " + assemblyName.Name.ToString() + assemblyName.Version.ToString(), // .NET和Furion版本
|
||||
NetworkSpeed = "",//"上行" + Send / 1024 + "kb/s 下行" + Received / 1024 + "kb/s" // 网络速度
|
||||
// Cpu名称
|
||||
CpuName = GetCPUName(),
|
||||
// Cpu基准速度
|
||||
CpuBaseSpeed = GetCPUSpeed(),
|
||||
// 内存总量
|
||||
TotalRam = GetRamInfo().Total,
|
||||
// 运行时间
|
||||
RunTime = (long)(DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds,
|
||||
// 磁盘信息
|
||||
DiskInfo = GetDiskInfo(),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态获取网络信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static dynamic GetMachineNetWorkInfo()
|
||||
{
|
||||
//var networkInfo = NetworkInfo.GetNetworkInfo();
|
||||
//var (Received, Send) = networkInfo.GetInternetSpeed(1000);
|
||||
////int Send, Received;
|
||||
////while (true)
|
||||
////{
|
||||
//// var tmp = networkInfo.GetInternetSpeed(1000);
|
||||
//// if (tmp.Send > 0 || tmp.Received > 0)
|
||||
//// {
|
||||
//// Send = tmp.Send;
|
||||
//// Received = tmp.Received;
|
||||
//// break;
|
||||
//// }
|
||||
//// Thread.Sleep(500);
|
||||
////}
|
||||
|
||||
return new
|
||||
{
|
||||
SendAndReceived = "",// "上行" + Math.Round(networkInfo.SendLength / 1024.0 / 1024 / 1024, 2) + "GB 下行" + Math.Round(networkInfo.ReceivedLength / 1024.0 / 1024 / 1024, 2) + "GB", // 上下行流量统计
|
||||
NetworkSpeed = ""//"上行" + Send / 1024 + "kb/s 下行" + Received / 1024 + "kb/s" // 网络速度
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否Linux
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static bool IsUnix()
|
||||
{
|
||||
return RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
}
|
||||
|
||||
private static string GetCPUName()
|
||||
{
|
||||
string result;
|
||||
if (IsUnix())
|
||||
{
|
||||
// ??????
|
||||
var output = ShellUtil.Bash("");
|
||||
result = output.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = ShellUtil.Cmd("wmic", "cpu get Name");
|
||||
result = output.Replace("Name", string.Empty).Trim();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetCPUSpeed()
|
||||
{
|
||||
string result;
|
||||
if (IsUnix())
|
||||
{
|
||||
// ??????
|
||||
var output = ShellUtil.Bash("");
|
||||
result = output.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = ShellUtil.Cmd("wmic", "cpu get CurrentClockSpeed");
|
||||
result = output.Replace("CurrentClockSpeed", string.Empty).Trim();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Dictionary<string, string>> GetDiskInfo()
|
||||
{
|
||||
var result = new List<Dictionary<string, string>>();
|
||||
if (IsUnix())
|
||||
{
|
||||
// ??????
|
||||
var output = ShellUtil.Bash("");
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = ShellUtil.Cmd("wmic", "LOGICALDISK get Name,Description,FileSystem,Size,FreeSpace");
|
||||
var strArray = output.Replace("\r", "").Trim().Split('\n')
|
||||
.Select(p => System.Text.RegularExpressions.Regex.Replace(p.Trim(), @"\s+", ",").Split(','));
|
||||
var keyArray = strArray.First();
|
||||
var valueArray = strArray.Where((p, i) => i > 0).ToArray();
|
||||
foreach(var value in valueArray)
|
||||
{
|
||||
var dict = new Dictionary<string, string>();
|
||||
for(var i = 0;i<keyArray.Length;i++)
|
||||
{
|
||||
dict.Add(keyArray[i], value[i]);
|
||||
}
|
||||
result.Add(dict);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取CPU使用率
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetCPURate()
|
||||
{
|
||||
string result;
|
||||
if (IsUnix())
|
||||
{
|
||||
var output = ShellUtil.Bash("top -b -n1 | grep \"Cpu(s)\" | awk '{print $2 + $4}'");
|
||||
result = output.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = ShellUtil.Cmd("wmic", "cpu get LoadPercentage");
|
||||
result = output.Replace("LoadPercentage", string.Empty).Trim();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取系统运行时间
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetRunTime()
|
||||
{
|
||||
return FormatTime((long)(DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds);
|
||||
//return DateTimeUtil.FormatTime(Environment.TickCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取内存信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static dynamic GetRamInfo()
|
||||
{
|
||||
if (IsUnix())
|
||||
{
|
||||
var output = ShellUtil.Bash("free -m");
|
||||
var lines = output.Split("\n");
|
||||
var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries);
|
||||
return new
|
||||
{
|
||||
Total = double.Parse(memory[1]),
|
||||
Used = double.Parse(memory[2]),
|
||||
Free = double.Parse(memory[3])
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = ShellUtil.Cmd("wmic", "OS get FreePhysicalMemory,TotalVisibleMemorySize /Value");
|
||||
var lines = output.Trim().Split("\n");
|
||||
var freeMemoryParts = lines[0].Split("=", StringSplitOptions.RemoveEmptyEntries);
|
||||
var totalMemoryParts = lines[1].Split("=", StringSplitOptions.RemoveEmptyEntries);
|
||||
var total = Math.Round(double.Parse(totalMemoryParts[1]) / 1024, 2);
|
||||
var free = Math.Round(double.Parse(freeMemoryParts[1]) / 1024, 2);
|
||||
return new
|
||||
{
|
||||
Total = total,
|
||||
Free = free,
|
||||
Used = total - free
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫秒转天时分秒
|
||||
/// </summary>
|
||||
/// <param name="ms"></param>
|
||||
/// <returns></returns>
|
||||
private static string FormatTime(long ms)
|
||||
{
|
||||
int ss = 1000;
|
||||
int mi = ss * 60;
|
||||
int hh = mi * 60;
|
||||
int dd = hh * 24;
|
||||
|
||||
long day = ms / dd;
|
||||
long hour = (ms - day * dd) / hh;
|
||||
long minute = (ms - day * dd - hour * hh) / mi;
|
||||
long second = (ms - day * dd - hour * hh - minute * mi) / ss;
|
||||
//long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
|
||||
|
||||
string sDay = day < 10 ? "0" + day : "" + day; //天
|
||||
string sHour = hour < 10 ? "0" + hour : "" + hour;//小时
|
||||
string sMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
|
||||
string sSecond = second < 10 ? "0" + second : "" + second;//秒
|
||||
//string sMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒
|
||||
//sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : "" + sMilliSecond;
|
||||
return string.Format("{0} 天 {1} 小时 {2} 分 {3} 秒", sDay, sHour, sMinute, sSecond);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取外网IP和地理位置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task<string> GetWanIpFromPCOnline()
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
var url = "http://whois.pconline.com.cn/ipJson.jsp";
|
||||
var stream = await url.GetAsStreamAsync();
|
||||
var streamReader = new StreamReader(stream, Encoding.GetEncoding("GBK"));
|
||||
var html = streamReader.ReadToEnd();
|
||||
var tmp = html[(html.IndexOf("({") + 2)..].Split(",");
|
||||
var ipAddr = tmp[0].Split(":")[1] + "【" + tmp[7].Split(":")[1] + "】";
|
||||
return ipAddr.Replace("\"", "");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统Shell命令
|
||||
/// </summary>
|
||||
public class ShellUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Bash命令
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <returns></returns>
|
||||
public static string Bash(string command)
|
||||
{
|
||||
var escapedArgs = command.Replace("\"", "\\\"");
|
||||
var process = new Process()
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/bash",
|
||||
Arguments = $"-c \"{escapedArgs}\"",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
}
|
||||
};
|
||||
process.Start();
|
||||
string result = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
process.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// cmd命令
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public static string Cmd(string fileName, string args)
|
||||
{
|
||||
string output = string.Empty;
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true
|
||||
};
|
||||
using (var process = Process.Start(info))
|
||||
{
|
||||
output = process.StandardOutput.ReadToEnd();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NetworkInfo
|
||||
{
|
||||
private readonly NetworkInterface _instance;
|
||||
public NetworkInterface NetworkInterface => _instance;
|
||||
private readonly Lazy<IPInterfaceStatistics> _statistics;
|
||||
private readonly Lazy<IPAddress> _addressIpv4;
|
||||
|
||||
public IPAddress AddressIpv4 => _addressIpv4.Value; // IPv4 地址
|
||||
public string Mac => _instance?.GetPhysicalAddress().ToString(); // Mac地址
|
||||
public string Id => _instance?.Id; // 网络适配器的标识符
|
||||
public long ReceivedLength => _statistics.Value.BytesReceived; // 网络下载总量
|
||||
public long SendLength => _statistics.Value.BytesSent; // 网络上传总量
|
||||
|
||||
private NetworkInfo(NetworkInterface network)
|
||||
{
|
||||
_instance = network;
|
||||
_statistics = new Lazy<IPInterfaceStatistics>(() => _instance?.GetIPStatistics());
|
||||
//_Ipv4Statistics = new Lazy<IPv4InterfaceStatistics>(() => _instance.GetIPv4Statistics());
|
||||
//_AddressIpv6 = new Lazy<IPAddress>(() => _instance.GetIPProperties().UnicastAddresses
|
||||
// .FirstOrDefault(x => x.IPv4Mask.ToString().Equals("0.0.0.0")).Address);
|
||||
_addressIpv4 = new Lazy<IPAddress>(() => _instance?.GetIPProperties().UnicastAddresses
|
||||
.FirstOrDefault(x => !x.IPv4Mask.ToString().Equals("0.0.0.0")).Address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前正在联网的网卡信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static NetworkInfo GetNetworkInfo()
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
return new NetworkInfo(NetworkInterface.GetAllNetworkInterfaces()
|
||||
.FirstOrDefault(x => x.NetworkInterfaceType != NetworkInterfaceType.Loopback
|
||||
&& x.NetworkInterfaceType != NetworkInterfaceType.Ethernet));
|
||||
|
||||
return new NetworkInfo(NetworkInterface.GetAllNetworkInterfaces()
|
||||
.FirstOrDefault(x => x.OperationalStatus == OperationalStatus.Up
|
||||
&& x.NetworkInterfaceType != NetworkInterfaceType.Loopback
|
||||
&& x.NetworkInterfaceType != NetworkInterfaceType.Ethernet));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前网卡的网络速度
|
||||
/// </summary>
|
||||
/// <param name="Milliseconds"></param>
|
||||
/// <returns></returns>
|
||||
public (int Received, int Send) GetInternetSpeed(int Milliseconds)
|
||||
{
|
||||
var newNetwork = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(x => x.Id == Id).GetIPStatistics();
|
||||
|
||||
long rec = ReceivedLength;
|
||||
long send = SendLength;
|
||||
Thread.Sleep(Milliseconds);
|
||||
return ((int)(newNetwork.BytesReceived - rec), (int)(newNetwork.BytesSent - send));
|
||||
}
|
||||
}
|
||||
}
|
||||
59
20220330_Vote/Ewide.Core/Util/MailHelper.cs
Normal file
59
20220330_Vote/Ewide.Core/Util/MailHelper.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public class MailHelper
|
||||
{
|
||||
public string Message { set; get; }
|
||||
public string UserMailAddress { set; get; }
|
||||
/// <summary>
|
||||
/// 邮箱类
|
||||
/// </summary>
|
||||
/// <param name="message">发送的信息</param>
|
||||
/// <param name="userMailAddress">用户的地址</param>
|
||||
public MailHelper(string message, string userMailAddress)
|
||||
{
|
||||
//MailHelper mail = new MailHelper("第一次发送邮箱测试", "591410538@qq.com");
|
||||
//mail.Send();
|
||||
Message = message;
|
||||
UserMailAddress = userMailAddress;
|
||||
}
|
||||
public void Send()
|
||||
{
|
||||
string account = App.Configuration["Mail:Account"];
|
||||
string passWord = App.Configuration["Mail:PassWord"];
|
||||
//var options = Options.Create(options: new MemoryCacheOptions());
|
||||
//IMemoryCache cache = new MemoryCache(options);
|
||||
SmtpClient smtpClient = new SmtpClient();
|
||||
smtpClient.EnableSsl = true;
|
||||
smtpClient.UseDefaultCredentials = false;
|
||||
smtpClient.Host = App.Configuration["Mail:Host"];
|
||||
smtpClient.Credentials = new System.Net.NetworkCredential(account, passWord);
|
||||
smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
|
||||
|
||||
MailMessage mailMessage = new MailMessage();
|
||||
MailAddress fromAddr = new MailAddress(account);
|
||||
mailMessage.From = fromAddr;
|
||||
mailMessage.To.Add(UserMailAddress);
|
||||
mailMessage.Subject = App.Configuration["Mail:Subject"];
|
||||
mailMessage.BodyEncoding = Encoding.UTF8;
|
||||
mailMessage.IsBodyHtml = true;
|
||||
mailMessage.Priority = MailPriority.Low;
|
||||
mailMessage.Body = Message;
|
||||
try
|
||||
{
|
||||
smtpClient.Send(mailMessage);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.xg1100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
232
20220330_Vote/Ewide.Core/Util/MimeMapping.cs
Normal file
232
20220330_Vote/Ewide.Core/Util/MimeMapping.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public class MimeMapping
|
||||
{
|
||||
private static Hashtable _mimeMappingTable;
|
||||
|
||||
private static void AddMimeMapping(string extension, string MimeType)
|
||||
{
|
||||
MimeMapping._mimeMappingTable.Add(extension, MimeType);
|
||||
}
|
||||
|
||||
public static string GetMimeMapping(string FileName)
|
||||
{
|
||||
string text = null;
|
||||
int num = FileName.LastIndexOf('.');
|
||||
if (0 < num && num > FileName.LastIndexOf('\\'))
|
||||
{
|
||||
text = (string)MimeMapping._mimeMappingTable[FileName.Substring(num)];
|
||||
}
|
||||
if (text == null)
|
||||
{
|
||||
text = (string)MimeMapping._mimeMappingTable[".*"];
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
static MimeMapping()
|
||||
{
|
||||
MimeMapping._mimeMappingTable = new Hashtable(190, StringComparer.CurrentCultureIgnoreCase);
|
||||
MimeMapping.AddMimeMapping(".323", "text/h323");
|
||||
MimeMapping.AddMimeMapping(".asx", "video/x-ms-asf");
|
||||
MimeMapping.AddMimeMapping(".acx", "application/internet-property-stream");
|
||||
MimeMapping.AddMimeMapping(".ai", "application/postscript");
|
||||
MimeMapping.AddMimeMapping(".aif", "audio/x-aiff");
|
||||
MimeMapping.AddMimeMapping(".aiff", "audio/aiff");
|
||||
MimeMapping.AddMimeMapping(".axs", "application/olescript");
|
||||
MimeMapping.AddMimeMapping(".aifc", "audio/aiff");
|
||||
MimeMapping.AddMimeMapping(".asr", "video/x-ms-asf");
|
||||
MimeMapping.AddMimeMapping(".avi", "video/x-msvideo");
|
||||
MimeMapping.AddMimeMapping(".asf", "video/x-ms-asf");
|
||||
MimeMapping.AddMimeMapping(".au", "audio/basic");
|
||||
MimeMapping.AddMimeMapping(".application", "application/x-ms-application");
|
||||
MimeMapping.AddMimeMapping(".bin", "application/octet-stream");
|
||||
MimeMapping.AddMimeMapping(".bas", "text/plain");
|
||||
MimeMapping.AddMimeMapping(".bcpio", "application/x-bcpio");
|
||||
MimeMapping.AddMimeMapping(".bmp", "image/bmp");
|
||||
MimeMapping.AddMimeMapping(".cdf", "application/x-cdf");
|
||||
MimeMapping.AddMimeMapping(".cat", "application/vndms-pkiseccat");
|
||||
MimeMapping.AddMimeMapping(".crt", "application/x-x509-ca-cert");
|
||||
MimeMapping.AddMimeMapping(".c", "text/plain");
|
||||
MimeMapping.AddMimeMapping(".css", "text/css");
|
||||
MimeMapping.AddMimeMapping(".cer", "application/x-x509-ca-cert");
|
||||
MimeMapping.AddMimeMapping(".crl", "application/pkix-crl");
|
||||
MimeMapping.AddMimeMapping(".cmx", "image/x-cmx");
|
||||
MimeMapping.AddMimeMapping(".csh", "application/x-csh");
|
||||
MimeMapping.AddMimeMapping(".cod", "image/cis-cod");
|
||||
MimeMapping.AddMimeMapping(".cpio", "application/x-cpio");
|
||||
MimeMapping.AddMimeMapping(".clp", "application/x-msclip");
|
||||
MimeMapping.AddMimeMapping(".crd", "application/x-mscardfile");
|
||||
MimeMapping.AddMimeMapping(".deploy", "application/octet-stream");
|
||||
MimeMapping.AddMimeMapping(".dll", "application/x-msdownload");
|
||||
MimeMapping.AddMimeMapping(".dot", "application/msword");
|
||||
MimeMapping.AddMimeMapping(".doc", "application/msword");
|
||||
MimeMapping.AddMimeMapping(".dvi", "application/x-dvi");
|
||||
MimeMapping.AddMimeMapping(".dir", "application/x-director");
|
||||
MimeMapping.AddMimeMapping(".dxr", "application/x-director");
|
||||
MimeMapping.AddMimeMapping(".der", "application/x-x509-ca-cert");
|
||||
MimeMapping.AddMimeMapping(".dib", "image/bmp");
|
||||
MimeMapping.AddMimeMapping(".dcr", "application/x-director");
|
||||
MimeMapping.AddMimeMapping(".disco", "text/xml");
|
||||
MimeMapping.AddMimeMapping(".exe", "application/octet-stream");
|
||||
MimeMapping.AddMimeMapping(".etx", "text/x-setext");
|
||||
MimeMapping.AddMimeMapping(".evy", "application/envoy");
|
||||
MimeMapping.AddMimeMapping(".eml", "message/rfc822");
|
||||
MimeMapping.AddMimeMapping(".eps", "application/postscript");
|
||||
MimeMapping.AddMimeMapping(".flr", "x-world/x-vrml");
|
||||
MimeMapping.AddMimeMapping(".fif", "application/fractals");
|
||||
MimeMapping.AddMimeMapping(".gtar", "application/x-gtar");
|
||||
MimeMapping.AddMimeMapping(".gif", "image/gif");
|
||||
MimeMapping.AddMimeMapping(".gz", "application/x-gzip");
|
||||
MimeMapping.AddMimeMapping(".hta", "application/hta");
|
||||
MimeMapping.AddMimeMapping(".htc", "text/x-component");
|
||||
MimeMapping.AddMimeMapping(".htt", "text/webviewhtml");
|
||||
MimeMapping.AddMimeMapping(".h", "text/plain");
|
||||
MimeMapping.AddMimeMapping(".hdf", "application/x-hdf");
|
||||
MimeMapping.AddMimeMapping(".hlp", "application/winhlp");
|
||||
MimeMapping.AddMimeMapping(".html", "text/html");
|
||||
MimeMapping.AddMimeMapping(".htm", "text/html");
|
||||
MimeMapping.AddMimeMapping(".hqx", "application/mac-binhex40");
|
||||
MimeMapping.AddMimeMapping(".isp", "application/x-internet-signup");
|
||||
MimeMapping.AddMimeMapping(".iii", "application/x-iphone");
|
||||
MimeMapping.AddMimeMapping(".ief", "image/ief");
|
||||
MimeMapping.AddMimeMapping(".ivf", "video/x-ivf");
|
||||
MimeMapping.AddMimeMapping(".ins", "application/x-internet-signup");
|
||||
MimeMapping.AddMimeMapping(".ico", "image/x-icon");
|
||||
MimeMapping.AddMimeMapping(".jpg", "image/jpeg");
|
||||
MimeMapping.AddMimeMapping(".jfif", "image/pjpeg");
|
||||
MimeMapping.AddMimeMapping(".jpe", "image/jpeg");
|
||||
MimeMapping.AddMimeMapping(".jpeg", "image/jpeg");
|
||||
MimeMapping.AddMimeMapping(".js", "application/x-javascript");
|
||||
MimeMapping.AddMimeMapping(".lsx", "video/x-la-asf");
|
||||
MimeMapping.AddMimeMapping(".latex", "application/x-latex");
|
||||
MimeMapping.AddMimeMapping(".lsf", "video/x-la-asf");
|
||||
MimeMapping.AddMimeMapping(".manifest", "application/x-ms-manifest");
|
||||
MimeMapping.AddMimeMapping(".mhtml", "message/rfc822");
|
||||
MimeMapping.AddMimeMapping(".mny", "application/x-msmoney");
|
||||
MimeMapping.AddMimeMapping(".mht", "message/rfc822");
|
||||
MimeMapping.AddMimeMapping(".mid", "audio/mid");
|
||||
MimeMapping.AddMimeMapping(".mpv2", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".man", "application/x-troff-man");
|
||||
MimeMapping.AddMimeMapping(".mvb", "application/x-msmediaview");
|
||||
MimeMapping.AddMimeMapping(".mpeg", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".m3u", "audio/x-mpegurl");
|
||||
MimeMapping.AddMimeMapping(".mdb", "application/x-msaccess");
|
||||
MimeMapping.AddMimeMapping(".mpp", "application/vnd.ms-project");
|
||||
MimeMapping.AddMimeMapping(".m1v", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".mpa", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".me", "application/x-troff-me");
|
||||
MimeMapping.AddMimeMapping(".m13", "application/x-msmediaview");
|
||||
MimeMapping.AddMimeMapping(".movie", "video/x-sgi-movie");
|
||||
MimeMapping.AddMimeMapping(".m14", "application/x-msmediaview");
|
||||
MimeMapping.AddMimeMapping(".mpe", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".mp2", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".mov", "video/quicktime");
|
||||
MimeMapping.AddMimeMapping(".mp3", "audio/mpeg");
|
||||
MimeMapping.AddMimeMapping(".mpg", "video/mpeg");
|
||||
MimeMapping.AddMimeMapping(".ms", "application/x-troff-ms");
|
||||
MimeMapping.AddMimeMapping(".nc", "application/x-netcdf");
|
||||
MimeMapping.AddMimeMapping(".nws", "message/rfc822");
|
||||
MimeMapping.AddMimeMapping(".oda", "application/oda");
|
||||
MimeMapping.AddMimeMapping(".ods", "application/oleobject");
|
||||
MimeMapping.AddMimeMapping(".pmc", "application/x-perfmon");
|
||||
MimeMapping.AddMimeMapping(".p7r", "application/x-pkcs7-certreqresp");
|
||||
MimeMapping.AddMimeMapping(".p7b", "application/x-pkcs7-certificates");
|
||||
MimeMapping.AddMimeMapping(".p7s", "application/pkcs7-signature");
|
||||
MimeMapping.AddMimeMapping(".pmw", "application/x-perfmon");
|
||||
MimeMapping.AddMimeMapping(".ps", "application/postscript");
|
||||
MimeMapping.AddMimeMapping(".p7c", "application/pkcs7-mime");
|
||||
MimeMapping.AddMimeMapping(".pbm", "image/x-portable-bitmap");
|
||||
MimeMapping.AddMimeMapping(".ppm", "image/x-portable-pixmap");
|
||||
MimeMapping.AddMimeMapping(".pub", "application/x-mspublisher");
|
||||
MimeMapping.AddMimeMapping(".pnm", "image/x-portable-anymap");
|
||||
MimeMapping.AddMimeMapping(".png", "image/png");
|
||||
MimeMapping.AddMimeMapping(".pml", "application/x-perfmon");
|
||||
MimeMapping.AddMimeMapping(".p10", "application/pkcs10");
|
||||
MimeMapping.AddMimeMapping(".pfx", "application/x-pkcs12");
|
||||
MimeMapping.AddMimeMapping(".p12", "application/x-pkcs12");
|
||||
MimeMapping.AddMimeMapping(".pdf", "application/pdf");
|
||||
MimeMapping.AddMimeMapping(".pps", "application/vnd.ms-powerpoint");
|
||||
MimeMapping.AddMimeMapping(".p7m", "application/pkcs7-mime");
|
||||
MimeMapping.AddMimeMapping(".pko", "application/vndms-pkipko");
|
||||
MimeMapping.AddMimeMapping(".ppt", "application/vnd.ms-powerpoint");
|
||||
MimeMapping.AddMimeMapping(".pmr", "application/x-perfmon");
|
||||
MimeMapping.AddMimeMapping(".pma", "application/x-perfmon");
|
||||
MimeMapping.AddMimeMapping(".pot", "application/vnd.ms-powerpoint");
|
||||
MimeMapping.AddMimeMapping(".prf", "application/pics-rules");
|
||||
MimeMapping.AddMimeMapping(".pgm", "image/x-portable-graymap");
|
||||
MimeMapping.AddMimeMapping(".qt", "video/quicktime");
|
||||
MimeMapping.AddMimeMapping(".ra", "audio/x-pn-realaudio");
|
||||
MimeMapping.AddMimeMapping(".rgb", "image/x-rgb");
|
||||
MimeMapping.AddMimeMapping(".ram", "audio/x-pn-realaudio");
|
||||
MimeMapping.AddMimeMapping(".rmi", "audio/mid");
|
||||
MimeMapping.AddMimeMapping(".ras", "image/x-cmu-raster");
|
||||
MimeMapping.AddMimeMapping(".roff", "application/x-troff");
|
||||
MimeMapping.AddMimeMapping(".rtf", "application/rtf");
|
||||
MimeMapping.AddMimeMapping(".rtx", "text/richtext");
|
||||
MimeMapping.AddMimeMapping(".sv4crc", "application/x-sv4crc");
|
||||
MimeMapping.AddMimeMapping(".spc", "application/x-pkcs7-certificates");
|
||||
MimeMapping.AddMimeMapping(".setreg", "application/set-registration-initiation");
|
||||
MimeMapping.AddMimeMapping(".snd", "audio/basic");
|
||||
MimeMapping.AddMimeMapping(".stl", "application/vndms-pkistl");
|
||||
MimeMapping.AddMimeMapping(".setpay", "application/set-payment-initiation");
|
||||
MimeMapping.AddMimeMapping(".stm", "text/html");
|
||||
MimeMapping.AddMimeMapping(".shar", "application/x-shar");
|
||||
MimeMapping.AddMimeMapping(".sh", "application/x-sh");
|
||||
MimeMapping.AddMimeMapping(".sit", "application/x-stuffit");
|
||||
MimeMapping.AddMimeMapping(".spl", "application/futuresplash");
|
||||
MimeMapping.AddMimeMapping(".sct", "text/scriptlet");
|
||||
MimeMapping.AddMimeMapping(".scd", "application/x-msschedule");
|
||||
MimeMapping.AddMimeMapping(".sst", "application/vndms-pkicertstore");
|
||||
MimeMapping.AddMimeMapping(".src", "application/x-wais-source");
|
||||
MimeMapping.AddMimeMapping(".sv4cpio", "application/x-sv4cpio");
|
||||
MimeMapping.AddMimeMapping(".tex", "application/x-tex");
|
||||
MimeMapping.AddMimeMapping(".tgz", "application/x-compressed");
|
||||
MimeMapping.AddMimeMapping(".t", "application/x-troff");
|
||||
MimeMapping.AddMimeMapping(".tar", "application/x-tar");
|
||||
MimeMapping.AddMimeMapping(".tr", "application/x-troff");
|
||||
MimeMapping.AddMimeMapping(".tif", "image/tiff");
|
||||
MimeMapping.AddMimeMapping(".txt", "text/plain");
|
||||
MimeMapping.AddMimeMapping(".texinfo", "application/x-texinfo");
|
||||
MimeMapping.AddMimeMapping(".trm", "application/x-msterminal");
|
||||
MimeMapping.AddMimeMapping(".tiff", "image/tiff");
|
||||
MimeMapping.AddMimeMapping(".tcl", "application/x-tcl");
|
||||
MimeMapping.AddMimeMapping(".texi", "application/x-texinfo");
|
||||
MimeMapping.AddMimeMapping(".tsv", "text/tab-separated-values");
|
||||
MimeMapping.AddMimeMapping(".ustar", "application/x-ustar");
|
||||
MimeMapping.AddMimeMapping(".uls", "text/iuls");
|
||||
MimeMapping.AddMimeMapping(".vcf", "text/x-vcard");
|
||||
MimeMapping.AddMimeMapping(".wps", "application/vnd.ms-works");
|
||||
MimeMapping.AddMimeMapping(".wav", "audio/wav");
|
||||
MimeMapping.AddMimeMapping(".wrz", "x-world/x-vrml");
|
||||
MimeMapping.AddMimeMapping(".wri", "application/x-mswrite");
|
||||
MimeMapping.AddMimeMapping(".wks", "application/vnd.ms-works");
|
||||
MimeMapping.AddMimeMapping(".wmf", "application/x-msmetafile");
|
||||
MimeMapping.AddMimeMapping(".wcm", "application/vnd.ms-works");
|
||||
MimeMapping.AddMimeMapping(".wrl", "x-world/x-vrml");
|
||||
MimeMapping.AddMimeMapping(".wdb", "application/vnd.ms-works");
|
||||
MimeMapping.AddMimeMapping(".wsdl", "text/xml");
|
||||
MimeMapping.AddMimeMapping(".xap", "application/x-silverlight-app");
|
||||
MimeMapping.AddMimeMapping(".xml", "text/xml");
|
||||
MimeMapping.AddMimeMapping(".xlm", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xaf", "x-world/x-vrml");
|
||||
MimeMapping.AddMimeMapping(".xla", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xls", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xof", "x-world/x-vrml");
|
||||
MimeMapping.AddMimeMapping(".xlt", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xlc", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xsl", "text/xml");
|
||||
MimeMapping.AddMimeMapping(".xbm", "image/x-xbitmap");
|
||||
MimeMapping.AddMimeMapping(".xlw", "application/vnd.ms-excel");
|
||||
MimeMapping.AddMimeMapping(".xpm", "image/x-xpixmap");
|
||||
MimeMapping.AddMimeMapping(".xwd", "image/x-xwindowdump");
|
||||
MimeMapping.AddMimeMapping(".xsd", "text/xml");
|
||||
MimeMapping.AddMimeMapping(".z", "application/x-compress");
|
||||
MimeMapping.AddMimeMapping(".zip", "application/x-zip-compressed");
|
||||
MimeMapping.AddMimeMapping(".*", "application/octet-stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
103
20220330_Vote/Ewide.Core/Util/RSAHandler.cs
Normal file
103
20220330_Vote/Ewide.Core/Util/RSAHandler.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Furion;
|
||||
using Furion.FriendlyException;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.X509;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public static class RSAHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// XML 文件转成PEM 公钥格式
|
||||
/// </summary>
|
||||
/// <param name="xml"></param>
|
||||
/// <param name="saveFile"></param>
|
||||
/// <returns></returns>
|
||||
public static string Xml2PemPublic(string xml, string saveFile)
|
||||
{
|
||||
var rsa = new RSACryptoServiceProvider();
|
||||
rsa.FromXmlString(xml); var p = rsa.ExportParameters(false);
|
||||
RsaKeyParameters key = new RsaKeyParameters(false, new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent)); using (var sw = new StreamWriter(saveFile))
|
||||
{
|
||||
var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
|
||||
pemWriter.WriteObject(key);
|
||||
}
|
||||
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key); byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
|
||||
string publicKey = Convert.ToBase64String(serializedPublicBytes);
|
||||
return Format(publicKey, 1);
|
||||
}
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static string Format(string key, int type)
|
||||
{
|
||||
string result = string.Empty;
|
||||
int length = key.Length / 64;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
int start = i * 64;
|
||||
result = result + key.Substring(start, 64) + "\r\n";
|
||||
}
|
||||
result = result + key.Substring(length * 64);
|
||||
if (type == 1)
|
||||
{
|
||||
result = result.Insert(0, "-----BEGIN PUBLIC KEY-----\r\n");
|
||||
result += "\r\n-----END PUBLIC KEY-----";
|
||||
}
|
||||
if (type == 2)
|
||||
{
|
||||
result = result.Insert(0, "-----BEGIN PRIVATE KEY-----\r\n");
|
||||
result += "\r\n-----END PRIVATE KEY-----";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// RSA加密 公钥
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public static string RSAEncrypt(string content)
|
||||
{
|
||||
string publickey = App.Configuration["RSA:publickey"];
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
byte[] cipherbytes;
|
||||
rsa.FromXmlString(publickey);
|
||||
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
|
||||
return Convert.ToBase64String(cipherbytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RSA解密 私钥
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public static string RSADecrypt(string content)
|
||||
{
|
||||
string privatekey = App.Configuration["RSA:privatekey"];
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
byte[] cipherbytes;
|
||||
try
|
||||
{ //很有可能是报文被修改 情况很小
|
||||
rsa.FromXmlString(privatekey);
|
||||
cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
|
||||
return Encoding.UTF8.GetString(cipherbytes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
20220330_Vote/Ewide.Core/Util/StringExtensions.cs
Normal file
48
20220330_Vote/Ewide.Core/Util/StringExtensions.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 下划线转为驼峰
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <param name="initialsUppder"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToCamelCase(this string str, char split = '_', bool initialsUppder = true)
|
||||
{
|
||||
var _ = string.Join("",
|
||||
str.Split(split).Select(p => p.Length > 1 ?
|
||||
p.First().ToString().ToUpper() + p[1..] : p.ToUpper()
|
||||
)
|
||||
);
|
||||
|
||||
if (!initialsUppder && _.Length > 1)
|
||||
{
|
||||
_ = _.First().ToString().ToUpper() + _[1..];
|
||||
}
|
||||
|
||||
return _;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 驼峰转为下划线
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToUnderScoreCase(this string str)
|
||||
{
|
||||
var _ = new Regex(@"[A-Z]").Replace(str, "_$0");
|
||||
|
||||
if (_.Length > str.Length)
|
||||
{
|
||||
_ = _[1..];
|
||||
}
|
||||
|
||||
return _.ToLower();
|
||||
}
|
||||
}
|
||||
108
20220330_Vote/Ewide.Core/Util/TreeBuildUtil.cs
Normal file
108
20220330_Vote/Ewide.Core/Util/TreeBuildUtil.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ewide.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// 树基类
|
||||
/// </summary>
|
||||
public interface ITreeNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取节点id
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetId();
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点父id
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetPid();
|
||||
|
||||
/// <summary>
|
||||
/// 设置Children
|
||||
/// </summary>
|
||||
/// <param name="children"></param>
|
||||
void SetChildren(IList children);
|
||||
}
|
||||
public class TreeBuildSetting
|
||||
{
|
||||
public bool AddEmptyChildren { get; set; } = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归工具类,用于遍历有父子关系的节点,例如菜单树,字典树等等
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class TreeBuildUtil<T> where T : ITreeNode
|
||||
{
|
||||
TreeBuildSetting _setting;
|
||||
public TreeBuildUtil(TreeBuildSetting setting = null)
|
||||
{
|
||||
_setting = setting ?? new TreeBuildSetting();
|
||||
}
|
||||
/// <summary>
|
||||
/// 顶级节点的父节点Id(默认0)
|
||||
/// </summary>
|
||||
private readonly List<string> _rootParentIds = new List<string> { string.Empty, Guid.Empty.ToString() };
|
||||
|
||||
/// <summary>
|
||||
/// 构造树节点
|
||||
/// </summary>
|
||||
/// <param name="nodes"></param>
|
||||
/// <returns></returns>
|
||||
public List<T> DoTreeBuild(List<T> nodes)
|
||||
{
|
||||
nodes.ForEach(u => BuildChildNodes(nodes, u, new List<T>()));
|
||||
|
||||
var results = new List<T>();
|
||||
nodes.ForEach(u =>
|
||||
{
|
||||
if (_rootParentIds.Contains(u.GetPid()))
|
||||
results.Add(u);
|
||||
});
|
||||
|
||||
// 在未获取到根节点的情况下, 直接将最上级作为根节点
|
||||
if (results.Count < 1)
|
||||
{
|
||||
var ids = new List<string>();
|
||||
nodes.ForEach(u =>
|
||||
{
|
||||
ids.Add(u.GetId());
|
||||
});
|
||||
|
||||
nodes.ForEach(u =>
|
||||
{
|
||||
if (!ids.Contains(u.GetPid()))
|
||||
results.Add(u);
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造子节点集合
|
||||
/// </summary>
|
||||
/// <param name="totalNodes"></param>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="childNodeLists"></param>
|
||||
private void BuildChildNodes(List<T> totalNodes, T node, List<T> childNodeLists)
|
||||
{
|
||||
var nodeSubLists = new List<T>();
|
||||
totalNodes.ForEach(u =>
|
||||
{
|
||||
if (u.GetPid().Equals(node.GetId()))
|
||||
nodeSubLists.Add(u);
|
||||
});
|
||||
nodeSubLists.ForEach(u => BuildChildNodes(totalNodes, u, new List<T>()));
|
||||
childNodeLists.AddRange(nodeSubLists);
|
||||
if (childNodeLists.Count > 0 || _setting.AddEmptyChildren)
|
||||
{
|
||||
node.SetChildren(childNodeLists);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
20220330_Vote/Ewide.Core/Util/TypeHelper.cs
Normal file
83
20220330_Vote/Ewide.Core/Util/TypeHelper.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public static class TypeHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 动态创建List<?> 泛型
|
||||
/// </summary>
|
||||
/// <param name="t">Type类</param>
|
||||
/// <param name="items">数据源</param>
|
||||
/// <returns></returns>
|
||||
public static object MakeList(this Type t, params object[] items)
|
||||
{
|
||||
Type type = typeof(List<>).MakeGenericType(t);
|
||||
object list = Activator.CreateInstance(type);
|
||||
System.Collections.IList ilist = list as System.Collections.IList;
|
||||
foreach (object o in items)
|
||||
ilist.Add(o);
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态创建List<?> 泛型
|
||||
/// </summary>
|
||||
/// <param name="t">Type类</param>
|
||||
/// <param name="objList">数据源</param>
|
||||
/// <returns></returns>
|
||||
public static object MakeList(this Type t, Object objList)
|
||||
{
|
||||
Type type = typeof(List<>).MakeGenericType(t);
|
||||
object list = Activator.CreateInstance(type);
|
||||
System.Collections.IList ilist = list as System.Collections.IList;
|
||||
var collection = objList as System.Collections.IEnumerable;
|
||||
if (collection != null)
|
||||
{
|
||||
foreach (object obj in collection)
|
||||
{
|
||||
ilist.Add(obj);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态创建List<?> 泛型s
|
||||
/// </summary>
|
||||
/// <param name="hostType">Type类</param>
|
||||
/// <param name="table">数据源</param>
|
||||
/// <returns></returns>
|
||||
public static object DataTableToList(this Type hostType, DataTable table)
|
||||
{
|
||||
Type type = typeof(List<>).MakeGenericType(hostType);
|
||||
object list = Activator.CreateInstance(type);
|
||||
System.Collections.IList ilist = list as System.Collections.IList;
|
||||
|
||||
object host = Activator.CreateInstance(hostType);
|
||||
string tempName = string.Empty;
|
||||
foreach (DataRow item in table.Rows)
|
||||
{
|
||||
PropertyInfo[] proList = hostType.GetProperties();
|
||||
foreach (PropertyInfo propertyInfo in proList)
|
||||
{
|
||||
tempName = propertyInfo.Name;
|
||||
if (table.Columns.Contains(tempName))
|
||||
{
|
||||
Object value = item[tempName];
|
||||
if (value!=null)
|
||||
{
|
||||
propertyInfo.SetValue(host,value, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
ilist.Add(host);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
171
20220330_Vote/Ewide.Core/Util/XmlSerializerUtil.cs
Normal file
171
20220330_Vote/Ewide.Core/Util/XmlSerializerUtil.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
using Furion;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Ewide.Core.Util
|
||||
{
|
||||
public class XmlSerializerUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// XML 要读取的路径
|
||||
/// </summary>
|
||||
private string DirPath { set; get; }
|
||||
/// <summary>
|
||||
/// 当前程序集
|
||||
/// </summary>
|
||||
private string currentAssemblyName { get { return "Ewide.Core"; } }
|
||||
/// <summary>
|
||||
/// 读取文件夹下所有XML
|
||||
/// add-migration init -c defaultDbContext 备用数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<Type, object> ReaderALL()
|
||||
{
|
||||
string dirPath = CurrentDirPath();
|
||||
Dictionary<Type, object> dic = new Dictionary<Type, object>();
|
||||
DirectoryInfo folder = new DirectoryInfo(dirPath);
|
||||
foreach (FileInfo file in folder.GetFiles())
|
||||
{
|
||||
//除去.xml 后缀
|
||||
string className = file.Name.Remove(file.Name.Length - 4, 4);
|
||||
object obj = AppInfo(className);
|
||||
string XmlContext = StreamRead(file.FullName);
|
||||
//实例创建 出 类型集合
|
||||
var modelList = Activator.CreateInstance(typeof(List<>).MakeGenericType(new Type[] { obj.GetType() }));
|
||||
var list = Deserialize(modelList.GetType(), XmlContext);
|
||||
dic.Add(obj.GetType(), list);
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
/// <summary>
|
||||
/// 反序列化
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="xmlContent">XML内容</param>
|
||||
/// <returns></returns>
|
||||
private object Deserialize(Type type, string xmlContent)
|
||||
{
|
||||
object obj = null;
|
||||
using (StringReader sr = new StringReader(xmlContent))
|
||||
{
|
||||
XmlSerializer xmldes = new XmlSerializer(type);
|
||||
obj = xmldes.Deserialize(sr);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// 数据流读取
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
private string StreamRead(string path)
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(path, Encoding.Default))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 反射 根据类名 反射整个类 得到实例
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
private object AppInfo(string name)
|
||||
{
|
||||
if (name == "BsHouseProjectInfo") //BsHouseProjectInfo 这个类 写在 application 程序集
|
||||
{
|
||||
string fullNamei = string.Join('.', "Ewide.Application.Entity", name);
|
||||
return Assembly.Load("Ewide.Application").CreateInstance(fullNamei);
|
||||
}
|
||||
string fullName = string.Join('.', currentAssemblyName, name);
|
||||
return Assembly.Load(currentAssemblyName).CreateInstance(fullName);
|
||||
}
|
||||
/// <summary>
|
||||
/// 写入XML到磁盘
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="data">数据</param>
|
||||
/// <param name="className">XML名称</param>
|
||||
public void WriteXML(Type type, object data, string className)
|
||||
{
|
||||
string writePath = CurrentDirPath(className);
|
||||
using (FileStream fs = new FileStream(writePath, FileMode.OpenOrCreate))
|
||||
{
|
||||
XmlSerializer ser = new XmlSerializer(type);
|
||||
ser.Serialize(fs, data);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 要操作的文件夹目录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string CurrentDirPath()
|
||||
{
|
||||
// 在for 循环里, 不用每次都读取 下面的代码
|
||||
if (DirPath != null)
|
||||
return DirPath;
|
||||
|
||||
string targetPath = String.Empty;
|
||||
string appConfigPath = App.Configuration["WriteXmlPath:ReadSelect"] == "SeedData" ? App.Configuration["WriteXmlPath:SeedData"] : App.Configuration["WriteXmlPath:DataBase"];
|
||||
string path = Directory.GetCurrentDirectory();
|
||||
DirectoryInfo dirInfo = new DirectoryInfo(path);
|
||||
foreach (DirectoryInfo item in dirInfo.Parent.GetDirectories())
|
||||
{
|
||||
if (item.Name == currentAssemblyName)
|
||||
{
|
||||
var queryList = item.GetDirectories().Where(s => s.Name == appConfigPath);
|
||||
if (!queryList.Any()) item.CreateSubdirectory(appConfigPath);
|
||||
targetPath = item.GetDirectories(appConfigPath).FirstOrDefault().FullName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DirPath = targetPath;
|
||||
return targetPath;
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据类名 创建一个XML文件 写入数据
|
||||
/// </summary>
|
||||
/// <param name="className"></param>
|
||||
/// <returns></returns>
|
||||
private string CurrentDirPath(string className)
|
||||
{
|
||||
string path = CurrentDirPath();
|
||||
return string.Join(@"\", path, className + ".xml");
|
||||
}
|
||||
/// <summary>
|
||||
/// 写入种子数据 --不常用
|
||||
/// </summary>
|
||||
public void WriteDataSeed()
|
||||
{
|
||||
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.GetName().Name.Contains("Ewide.Core"));
|
||||
Type[] types = assembly.GetTypes();
|
||||
foreach (Type type in types)
|
||||
{
|
||||
//if (type.Name.EndsWith("SeedData"))
|
||||
if (type.Name.EndsWith("SysEmpExtOrgPos"))
|
||||
{
|
||||
object obHelper = Activator.CreateInstance(type);
|
||||
MethodInfo methodinfo = type.GetMethod("HasData");
|
||||
object objs = methodinfo.Invoke(obHelper, new object[] { null, null });
|
||||
Type objType = objs.GetType();
|
||||
//if (objType.Name == "SysEmpExtOrgPos[]" || objType.Name == "SysConfig[]" || objType.Name == "SysDictData[]" || objType.Name == "SysDictType[]" || objType.Name == "SysEmpPos[]" || objType.Name == "SysEmp[]" || objType.Name == "SysMenu[]" || objType.Name == "SysOrg[]" || objType.Name == "SysPos[]" || objType.Name == "SysRole[]" || objType.Name == "SysTenant[]" || objType.Name == "SysTimer[]" || objType.Name == "SysUser[]")
|
||||
if (objType.Name == "SysEmpExtOrgPos[]")
|
||||
{
|
||||
string className = objType.Name.Remove(objType.Name.Length - 2, 2);
|
||||
WriteXML(objType, objs, className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user