using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using ProtoBuf;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Tiobon.PublishHelper
{
///
/// 辅助类
///
public class Utility
{
#region 参数
///
/// 停止发布
///
public static bool m_StopPublish = false;
///
/// 替换控制指令
///
public static System.Text.RegularExpressions.Regex m_RegexUb = new System.Text.RegularExpressions.Regex(@"\u001b\[\d+[A-z]");
///
/// 测试服务器
///
public static string m_TestServerIp = "192.168.8.60";
#endregion
#region 事件
///
/// 记录日志
///
public static Action SendLogHandle;
public static void SendLog(string msg, bool status = false)
{
SendLogHandle("", msg);
if (status)
{
SetStatus(msg);
}
lock (m_Logs)
m_Logs.Add(msg);
}
public static void SendLog(string oprate, string msg, bool status = false)
{
SendLogHandle(oprate, msg);
if (status)
{
SetStatus(msg);
}
lock (m_Logs)
{
if (string.IsNullOrEmpty(oprate))
m_Logs.Add($"{msg}");
else
m_Logs.Add($"[{oprate}] {msg}");
}
}
///
/// 设置进度条显示/隐藏
///
public static Action SetProgressBarVisible;
///
/// 设置进度条状态
///
public static Action SetProgressBarValue;
///
/// 设置当前状态
///
public static Action SetStatus;
#endregion
#region 初始化
public static void Init()
{
ReadDevServer();
ReadPublishServer();
ReadOprateLog();
Thread log = new Thread(WriteLogger);
log.Start();
}
#endregion
#region 服务器管理
///
/// 开发服务器列表
///
public static List m_DevServers = new List();
///
/// 保存开发服务器配置
///
public static void SaveDevServer()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\DevServers.dat";
if (File.Exists(fname))
File.Delete(fname);
using (FileStream fs = new FileStream(fname, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
bf.Serialize(fs, m_DevServers);
}
}
catch { }
}
///
/// 读取开发服务器配置
///
public static void ReadDevServer()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\DevServers.dat";
if (File.Exists(fname))
{
using (FileStream fs = new FileStream(fname, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
m_DevServers = bf.Deserialize(fs) as List;
}
}
}
catch { }
if (m_DevServers is null)
{
m_DevServers = new List();
}
m_DevServers.ForEach(s =>
{
if (s.Hospitals is null)
{
s.Hospitals = new List();
}
});
}
///
/// 发布服务器列表
///
public static List m_PublishServers = new List();
///
/// 保存发布服务器配置
///
public static void SavePublishServer()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\PublishServers.dat";
if (File.Exists(fname))
File.Delete(fname);
using (FileStream fs = new FileStream(fname, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
bf.Serialize(fs, m_PublishServers);
}
}
catch { }
}
///
/// 读取发布服务器配置
///
public static void ReadPublishServer()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\PublishServers.dat";
if (File.Exists(fname))
{
using (FileStream fs = new FileStream(fname, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
m_PublishServers = bf.Deserialize(fs) as List;
}
}
}
catch { }
if (m_PublishServers is null)
{
m_PublishServers = new List();
}
m_PublishServers.ForEach(s =>
{
if (s.Folders is null)
s.Folders = new List();
s.Folders.ForEach(f =>
{
if (f.Files is null)
f.Files = new List();
});
});
}
#endregion
#region 操作记录
///
/// 操作记录
///
public static OprateLog m_OprateLog = new OprateLog();
///
/// 保存操作记录
///
public static void SaveOprateLog()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\OprateLog.dat";
if (File.Exists(fname))
File.Delete(fname);
using (FileStream fs = new FileStream(fname, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
bf.Serialize(fs, m_OprateLog);
}
}
catch { }
}
///
/// 读取操作记录
///
public static void ReadOprateLog()
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "\\OprateLog.dat";
if (File.Exists(fname))
{
using (FileStream fs = new FileStream(fname, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
//将list序列化到文件中
m_OprateLog = bf.Deserialize(fs) as OprateLog;
}
}
}
catch { }
if (m_OprateLog is null)
{
m_OprateLog = new OprateLog();
}
}
#endregion
#region Ping测试
///
/// Ping测试
///
///
///
///
public static bool Ping(string ip, bool b_log = true)
{
bool b_suc = false;
try
{
using (Ping ping = new Ping())
{
b_suc = ping.Send(ip, 2000).Status == IPStatus.Success;
}
}
catch
{
b_suc = false;
}
if (!b_suc && b_log)
{
SendLog(ip, "ping失败,不继续执行其他远程操作指令");
}
return b_suc;
}
#endregion
#region 获取临时文件名
///
/// 获取临时文件名
///
///
///
///
public static string GetTempFileName(string fname, bool random = true)
{
return $"{System.Environment.GetEnvironmentVariable("TEMP")}\\{fname}" + (random ? $"_{DateTime.Now.Ticks}" : "");
}
#endregion
#region 获取服务器状态
///
/// 获取服务器状态
///
///
///
public static (bool Success, double Cpu, double MemTotal, double MemUsed, double Disk) GetServerStatus(Server server)
{
var res = (false, 0, 0, 0, 0);
try
{
var (Success, Result) = SshHelper.ExcuteCmd(server, "cpu=`top -b -n 1 | awk 'NR>7{sum+=$9} END {print sum}'`\n mem=`free -m | awk 'NR==2{print $2,$3}'` \n disk=`df -h | grep \"home\" |awk '{{print $5}}'` \n echo \"$cpu,$mem,$disk\"", false);
if (Success)
{
//87,7981 4369,96%
var empties = Result.Trim('\n').Trim().Split(new string[] { "%", ",", " " }, StringSplitOptions.RemoveEmptyEntries);
if (empties.Length == 4)
{
return (true, double.Parse(empties[0]), double.Parse(empties[1]), double.Parse(empties[2]), double.Parse(empties[3]));
}
}
}
catch
{ }
return res;
}
#endregion
#region 日志
///
/// 停止记录日志
///
public static bool m_LogRun = true;
private static List m_Logs = new List();
///
/// 日志线程
///
private static void WriteLogger()
{
var path = AppDomain.CurrentDomain.BaseDirectory + "Log\\";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string fname = string.Empty;
var logs = new List();
while (m_LogRun)
{
try
{
lock (m_Logs)
{
if (m_Logs.Count > 0)
{
m_Logs.ForEach(s => logs.Add(s));
fname = path + DateTime.Now.ToString("yyyy_MM_dd") + ".txt";
m_Logs.Clear();
}
}
if (logs.Count > 0)
{
WriteLoggerToFile(fname, logs);
logs.Clear();
}
}
catch
{
// ignored
}
finally
{
System.Threading.Thread.Sleep(3000);
}
}
}
///
/// 日志写入文件
///
/// 文件名
/// 日志
private static void WriteLoggerToFile(string fname, List logs)
{
StringBuilder sb = new StringBuilder();
logs.ForEach(s => sb.AppendLine(DateTime.Now.ToString("HH:mm:ss") + "\t" + s));
if (!File.Exists(fname))
{
using (StreamWriter sw = File.CreateText(fname))
{
sw.Write(sb.ToString());
}
}
else
{
using (StreamWriter sw = File.AppendText(fname))
{
sw.Write(sb.ToString());
}
}
}
#endregion
#region 发布与打包锁
///
/// 查询锁定文件
///
///
///
///
///
public static bool LockDevFiles(Server server, string oprate)
{
bool b_in = false;
string lfname = GetTempFileName("lockfile");
string rfname = $"/tmp/lockfile";
if (SftpHelper.DownloadFile(server, rfname, lfname))
{
if (File.Exists(lfname))
{
SendLog(File.ReadAllText(lfname, Encoding.UTF8));
b_in = true;
}
}
else
{
File.WriteAllText(lfname, $"当前服务器 {server.Ip} 繁忙。用户 [{Environment.MachineName}] 正在 {oprate},请等待 [{Environment.MachineName}] 操作完毕...", Encoding.UTF8);
SftpHelper.UploadFile(server, lfname, rfname);
}
return b_in;
}
///
/// 删除锁定文件
///
///
public static void RemoveDevFiles(Server server)
{
SftpHelper.Delete(server, $"/tmp/lockfile");
}
#endregion
#region HTTP模板
public static CookieContainer m_Cookies = new CookieContainer();
public enum Compression
{
GZip,
Deflate,
None,
}
///
/// 获取HttpWebRequest模板
///
/// URL地址
/// POST
/// Cookies
///
public static HttpWebRequest GetHttpRequest(string url, string postdata, CookieContainer cookies, string header = null)
{
HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
request.CookieContainer = cookies;
request.ContentType = !string.IsNullOrEmpty(header) ? "application/json" : "application/x-www-form-urlencoded";
request.ServicePoint.ConnectionLimit = 300;
ServicePointManager.Expect100Continue = false;
request.Referer = url;
request.Accept = "*/*";
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)";
request.AllowAutoRedirect = true;
if (!string.IsNullOrEmpty(header))
request.Headers.Add("Authorization", header);
if (postdata != null && postdata != "")
{
request.Method = "POST";
byte[] byte_post = Encoding.Default.GetBytes(postdata);
request.ContentLength = byte_post.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(byte_post, 0, byte_post.Length);
}
}
else
{
request.Method = "GET";
}
return request;
}
///
/// 提取HttpWebResponse文本内容
///
/// HttpWebResponse响应包
///
public static string GetResponseContent(HttpWebResponse resp)
{
if (resp.StatusCode != HttpStatusCode.OK)
throw new Exception("远程服务器返回状态码: " + resp.StatusCode);
Encoding enc = Encoding.UTF8;
if (resp.CharacterSet != null && resp.CharacterSet != "")
enc = Encoding.GetEncoding(resp.CharacterSet);
Compression comp = Compression.None;
if (resp.ContentEncoding != null && resp.ContentEncoding.Trim().ToUpper() == "GZIP")
comp = Compression.GZip;
else if (resp.ContentEncoding != null && resp.ContentEncoding.Trim().ToUpper() == "DEFLATE")
comp = Compression.Deflate;
MemoryStream ms = new MemoryStream();
using (StreamWriter sw = new StreamWriter(ms, enc))
{
StreamReader sr;
switch (comp)
{
case Compression.GZip:
sr = new StreamReader(new System.IO.Compression.GZipStream(resp.GetResponseStream(), System.IO.Compression.CompressionMode.Decompress), enc);
break;
case Compression.Deflate:
sr = new StreamReader(new System.IO.Compression.DeflateStream(resp.GetResponseStream(), System.IO.Compression.CompressionMode.Decompress), enc);
break;
default:
sr = new StreamReader(resp.GetResponseStream(), enc);
break;
}
while (!sr.EndOfStream)
{
char[] buf = new char[16000];
int read = sr.ReadBlock(buf, 0, 16000);
StringBuilder sb = new StringBuilder();
sb.Append(buf, 0, read);
sw.Write(buf, 0, read);
}
sr.Close();
}
byte[] mbuf = ms.GetBuffer();
string sbuf = enc.GetString(mbuf);
return sbuf;
}
///
/// 获取HttpWebRequest返回值
///
/// URL地址
/// PostData
///
public static string GetHttpResult(string url, string postdata, string header = null)
{
try
{
HttpWebRequest request = GetHttpRequest(url, postdata, m_Cookies, header);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
m_Cookies.Add(response.Cookies);
return GetResponseContent(response);
}
catch
{
//Utilities.sendLog("连接 " + url + " 失败" + ex.Message);
return "";
}
}
///
/// 获取HttpWebRequest返回值
///
/// URL地址
/// PostData
///
public static Stream GetHttpResponse(string url, string postdata)
{
try
{
HttpWebRequest request = GetHttpRequest(url, postdata, m_Cookies);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return response.GetResponseStream();
}
catch
{
//Utilities.sendLog("连接 " + url + " 失败" + ex.Message);
return null;
}
}
///
/// 去除HTML标记
///
/// 包括HTML的源码
/// 已经去除后的文字
public static string RemoveHTMLFlag(string input)
{
input = Regex.Replace(input, @"", "", RegexOptions.IgnoreCase);
Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
input = regex.Replace(input, "");
input = Regex.Replace(input, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
input = Regex.Replace(input, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
input = Regex.Replace(input, @"-->", "", RegexOptions.IgnoreCase);
input = Regex.Replace(input, @"