You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
500 lines
19 KiB
C#
500 lines
19 KiB
C#
using Aspose.Cells;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using System.Collections.Concurrent;
|
|
using System.Data;
|
|
using System.Diagnostics;
|
|
using Txgy.RBS.DTO;
|
|
using Txgy.RBS.Framework;
|
|
using Txgy.RBS.Framework.Api;
|
|
using Txgy.RBS.Framework.FileWatcherHelper;
|
|
using Txgy.RBS.Framework.Models;
|
|
using Txgy.RBS.Framework.RedisHelper.Service;
|
|
using Txgy.RBS.IServices;
|
|
|
|
namespace Txgy.RBS.Services
|
|
{
|
|
public class ProcessManagerService
|
|
{
|
|
private readonly IMemoryCache _cache;
|
|
private readonly RedisListService _redisList;
|
|
private readonly IResultInfoService _resultInfoService;
|
|
|
|
public ProcessManagerService(RedisListService redisList, IResultInfoService resultInfoService, IMemoryCache cache)
|
|
{
|
|
MoniTimer.Interval = 10000;
|
|
MoniTimer.Elapsed += MoniTimer_Elapsed;
|
|
MoniTimer.Start();
|
|
this._redisList = redisList;
|
|
this._resultInfoService = resultInfoService;
|
|
_cache = cache;
|
|
RedisServer = new ProcessInfo()
|
|
{
|
|
ProName = "server",
|
|
StartTime = DateTime.Now,
|
|
State = true
|
|
};
|
|
}
|
|
public ProcessInfo RedisServer { get; set; }
|
|
|
|
private void MoniTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
foreach (var item in ProjectMonitor)
|
|
{
|
|
_redisList.Publish(CommonData.RedisPublish, Newtonsoft.Json.JsonConvert.SerializeObject(new
|
|
{
|
|
projectName = item.Key,
|
|
ProName = RedisServer.ProName,
|
|
RunState = RedisServer.State?1:0,
|
|
RunTime = (DateTime.Now - RedisServer.StartTime).TotalSeconds,
|
|
}));
|
|
foreach (var proValue in item.Value.GetType().GetProperties())
|
|
{
|
|
var pro = proValue.GetValue(item.Value) as ProcessInfo;
|
|
if (pro != null)
|
|
{
|
|
int sfp = FindProcess(pro);
|
|
if (sfp != 0)
|
|
{
|
|
pro.State = false;
|
|
Console.WriteLine($"{pro.ProName}程序重启中, path:{pro.ProPath}");
|
|
StartProcess(pro);
|
|
Thread.Sleep(20);
|
|
}
|
|
else
|
|
{
|
|
pro.State = true;
|
|
}
|
|
_redisList.Publish(CommonData.RedisPublish, Newtonsoft.Json.JsonConvert.SerializeObject(new
|
|
{
|
|
projectName=item.Key,
|
|
ProName = pro.ProName,
|
|
RunState = sfp == 0 ? 1 : 0,
|
|
RunTime = (DateTime.Now - pro.StartTime).TotalSeconds,
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ConcurrentDictionary<string, ProcessConfig> ProjectMonitor = new ConcurrentDictionary<string, ProcessConfig>();
|
|
|
|
public void StartMointor(string projectName, ProcessConfig processInfo)
|
|
{
|
|
if (!ProjectMonitor.ContainsKey(projectName))
|
|
{
|
|
ProjectMonitor.TryAdd(projectName, processInfo);
|
|
processInfo.FilesWatcherService.InitializeParams();
|
|
processInfo.FilesWatcherService.Start();
|
|
processInfo.FilesWatcherService.WatcherFileChanged = WatcherChanged;
|
|
}
|
|
}
|
|
System.Timers.Timer MoniTimer { get; set; } = new System.Timers.Timer();
|
|
public void StopMointor(string projectName)
|
|
{
|
|
if (ProjectMonitor.ContainsKey(projectName))
|
|
{
|
|
ProjectMonitor.TryRemove(projectName, out ProcessConfig process);
|
|
process.FilesWatcherService.Stop();
|
|
foreach (var proValue in process.GetType().GetProperties())
|
|
{
|
|
var pro = proValue.GetValue(process) as ProcessInfo;
|
|
if (pro != null)
|
|
{
|
|
_redisList.Publish(CommonData.RedisPublish, Newtonsoft.Json.JsonConvert.SerializeObject(new
|
|
{
|
|
projectName = projectName,
|
|
ProName = pro.ProName,
|
|
RunState = 0,
|
|
RunTime = (DateTime.Now - pro.StartTime).TotalSeconds,
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void WatcherChanged(MsEventModel msEvent, FileSystemEventArgs e)
|
|
{
|
|
|
|
var path= Path.GetDirectoryName(e.FullPath);
|
|
var dir = new DirectoryInfo(path);
|
|
var files= dir.GetFiles("*.json");
|
|
string name = $"HA.{msEvent.OriginTime.Year}{msEvent.OriginTime.Month:D2}{msEvent.OriginTime.Day:D2}T{msEvent.OriginTime.Hour:D2}{msEvent.OriginTime.Minute:D2}{msEvent.OriginTime.Second:D2}";
|
|
string jsonStr = string.Empty;
|
|
foreach (var item in files)
|
|
{
|
|
if (item.FullName.Contains(name))
|
|
{
|
|
jsonStr= File.ReadAllText(item.FullName);
|
|
break;
|
|
}
|
|
}
|
|
_resultInfoService.AddResultInfo(new ResultDTO
|
|
{
|
|
project_id = msEvent.ProjectId,
|
|
otime = msEvent.OriginTime.ToString("O"),
|
|
xlon = msEvent.EastCoordinate,
|
|
ylat = msEvent.NorthCoordinate,
|
|
depth = msEvent.Depth,
|
|
ml = msEvent.ML,
|
|
energy = msEvent.Energy,
|
|
json_str= jsonStr,
|
|
phases_count = msEvent.PhasesCount,
|
|
amps_count = msEvent.AmpsCount,
|
|
});
|
|
_redisList.Publish($"{msEvent.ProjectName}result", Newtonsoft.Json.JsonConvert.SerializeObject(new
|
|
{
|
|
projectName = msEvent.ProjectName,
|
|
otime = msEvent.OriginTime,
|
|
message = msEvent.ToString(),
|
|
jsonStr = jsonStr
|
|
}));
|
|
}
|
|
|
|
|
|
#region 方法
|
|
|
|
public ApiResult StartProject(string projectName, ProcessConfig processConfig)
|
|
{
|
|
int res = 0;
|
|
if (ProjectMonitor.ContainsKey(projectName))
|
|
{
|
|
return new ApiResult();
|
|
}
|
|
foreach (var item in processConfig.GetType().GetProperties())
|
|
{
|
|
var pro = item.GetValue(processConfig) as ProcessInfo;
|
|
if (pro != null && pro.IsEnable)
|
|
{
|
|
res = StartProcess(pro);
|
|
if (res != 0)
|
|
{
|
|
continue;
|
|
}
|
|
pro.StartTime = DateTime.Now;
|
|
pro.State = true;
|
|
// _cache.Set(pro.ProPath, pro);
|
|
Thread.Sleep(10);
|
|
}
|
|
}
|
|
StartMointor(projectName, processConfig);
|
|
|
|
if (res == 0)
|
|
{
|
|
return new ApiResult();
|
|
}
|
|
return new ApiResult() { Message = "操作失败" };
|
|
|
|
}
|
|
|
|
public ApiResult StopProject(string projectName)
|
|
{
|
|
int res = 0;
|
|
ProjectMonitor.TryGetValue(projectName, out ProcessConfig process);
|
|
if(process == null) { return new ApiResult(); }
|
|
foreach (var item in process.GetType().GetProperties())
|
|
{
|
|
var pro = item.GetValue(process) as ProcessInfo;
|
|
if (pro != null && pro.IsEnable)
|
|
{
|
|
res = KillProcess(pro);
|
|
if (res != 0)
|
|
{
|
|
break;
|
|
}
|
|
pro.State = false;
|
|
// _cache.Set(pro.ProPath, pro);
|
|
Thread.Sleep(10);
|
|
}
|
|
}
|
|
StopMointor(projectName);
|
|
if (res == 0)
|
|
{
|
|
return new ApiResult();
|
|
}
|
|
return new ApiResult() { Message = "操作失败" };
|
|
}
|
|
|
|
private bool CMDStartProcess(ProcessInfo proInfo)
|
|
{
|
|
//* Create your Process
|
|
Process process = new Process();
|
|
process.Exited += Process_Exited;
|
|
process.EnableRaisingEvents = true;
|
|
process.StartInfo.FileName = Path.GetFullPath(Path.Combine(proInfo.ProPath, proInfo.ProName + ".exe"));
|
|
process.StartInfo.WorkingDirectory = Path.GetFullPath(proInfo.ProPath);
|
|
process.StartInfo.Arguments = proInfo.ProParams;
|
|
Debug.WriteLine($"*******ProcessName:{process.StartInfo.FileName}, arguments:{process.StartInfo.Arguments}*********");
|
|
process.StartInfo.UseShellExecute = false;
|
|
process.StartInfo.RedirectStandardOutput = true;
|
|
process.StartInfo.RedirectStandardError = true;
|
|
process.StartInfo.CreateNoWindow = true;
|
|
//* Set your output and error (asynchronous) handlers
|
|
{
|
|
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
|
|
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
|
|
}
|
|
//* Start process and handlers
|
|
bool res = process.Start();
|
|
process.BeginOutputReadLine();
|
|
process.BeginErrorReadLine();
|
|
// process.WaitForExit();
|
|
return res;
|
|
}
|
|
|
|
private void Process_Exited(object? sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
|
|
{
|
|
Debug.WriteLine("output*************:{0},{1}", sendingProcess.ToString(), outLine.Data);
|
|
if (string.IsNullOrEmpty(outLine.Data)) return;
|
|
if (outLine.Data.Contains("ProcessSlice:"))
|
|
{
|
|
var pro = sendingProcess as Process;
|
|
if (pro != null)
|
|
{
|
|
|
|
}
|
|
}
|
|
else if (outLine.Data.Contains("ML "))
|
|
{
|
|
var pro = sendingProcess as Process;
|
|
if (pro != null)
|
|
{
|
|
var msEvent= new MsEventModel(outLine.Data) { CurrentTime = DateTime.Now };
|
|
Console.WriteLine($"processName:{pro.ProcessName},message:{outLine.Data}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public int StartProcess(ProcessInfo proInfo)
|
|
{
|
|
bool res = CMDStartProcess(proInfo);
|
|
int seInd = res ? 0 : 1;
|
|
return seInd;
|
|
}
|
|
/// <summary>
|
|
/// 结束进程
|
|
/// </summary>
|
|
/// <param name="processInfo"></param>
|
|
/// <returns>0=成功;1=未找到进程;-1=失败</returns>
|
|
private int KillProcess(ProcessInfo processInfo)
|
|
{
|
|
int ri = 0;
|
|
if (processInfo != null)
|
|
{
|
|
if (processInfo.ProName != null)
|
|
{
|
|
try
|
|
{
|
|
Process[] localByName = Process.GetProcessesByName(processInfo.ProName);
|
|
if (localByName.Length == 0)
|
|
{
|
|
ri = 1;
|
|
return ri;
|
|
}
|
|
foreach (var item in localByName)
|
|
{
|
|
item.Kill();
|
|
}
|
|
return ri;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查找进程
|
|
/// </summary>
|
|
/// <param name="processInfo"></param>
|
|
/// <returns>0=正在运行;1=未运行;-1=系统错误</returns>
|
|
private int FindProcess(ProcessInfo processInfo)
|
|
{
|
|
int ri = 0;
|
|
try
|
|
{
|
|
Process[] localByName = Process.GetProcessesByName(processInfo.ProName);
|
|
if (localByName.Length == 0)
|
|
{
|
|
ri = 1;
|
|
return ri;
|
|
}
|
|
else
|
|
{
|
|
List<Process> pro = null;
|
|
if (processInfo.ProName == "server")
|
|
{
|
|
pro = localByName.Where(p => p.MainModule.FileName.Contains(processInfo.ProName)).ToList();
|
|
}
|
|
else
|
|
{
|
|
pro = localByName.Where(p => p.MainModule.FileName.Contains(processInfo.ProPath)).ToList();
|
|
}
|
|
if (!pro.Any())
|
|
{
|
|
ri = 1;
|
|
}
|
|
return ri;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public string ProcessStatus { get; set; }
|
|
|
|
|
|
public ApiResult GetState(string projectName, int id)
|
|
{
|
|
ProcessInfo pro = null;
|
|
if(id==1)
|
|
{
|
|
pro = this.RedisServer;
|
|
}
|
|
ProjectMonitor.TryGetValue(projectName, out ProcessConfig process);
|
|
if (process == null || (id < 1|| id > 3)) { return new ApiResult(); }
|
|
pro = id == 1 ?pro:(id==2)? process.Apms : process.RecvMqtt;
|
|
int sfp = FindProcess(pro);
|
|
if (sfp != 0)
|
|
{
|
|
return new ApiResult { Code = System.Net.HttpStatusCode.NotFound };
|
|
}
|
|
return new ApiResult
|
|
{
|
|
Code = System.Net.HttpStatusCode.OK,
|
|
Data = new
|
|
{
|
|
name = pro.ProName,
|
|
state = sfp == 0 ? 1 : 0,
|
|
start_time = pro.StartTime,
|
|
running_time = (DateTime.Now - pro.StartTime).TotalSeconds,
|
|
}
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
public ApiResult ExportCSV(string fileName, List<StationDTO> stations)
|
|
{
|
|
DataTable dataTable = new DataTable();
|
|
string[] header = new string[] { "project_id", "net", "sta"," x2000", "y2000", "z2000", "sens", "begin", "stop", "sitenum" };
|
|
DataColumn da = new DataColumn();
|
|
foreach (var item in header)
|
|
{
|
|
dataTable.Columns.Add(item, typeof(string));
|
|
}
|
|
foreach (var sta in stations)
|
|
{
|
|
dataTable.Rows.Add(sta.project_id, sta.network,sta.num,sta.coord_e,sta.coord_n,sta.altitude,sta.sens,sta.begin_time,sta.end_time,sta.site_number);
|
|
}
|
|
return ExportExcel(fileName,dataTable, header);
|
|
}
|
|
/// 导出csv表格
|
|
/// </summary>
|
|
/// <param name="list">数据集合</param>
|
|
/// <param name="header">数据表头</param>
|
|
/// <param name=" title"> 标题</param>
|
|
/// <returns></returns>
|
|
private ApiResult ExportExcel(string fileName, DataTable dt, string[] header, string title = null)
|
|
{
|
|
Workbook wb = new Workbook();
|
|
try
|
|
{
|
|
Worksheet sheet = wb.Worksheets[0];
|
|
sheet.Name = "station数据";
|
|
if (dt.Rows.Count <= 0)
|
|
{
|
|
return new ApiResult() { Code= System.Net.HttpStatusCode.NoContent,Message="没有数据"};
|
|
}
|
|
// 为单元格添加样式
|
|
Aspose.Cells.Style style = wb.CreateStyle();
|
|
//style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center; //设置居中
|
|
style.Font.Size = 20;//文字大小
|
|
style.Font.IsBold = true;//粗体
|
|
style.HorizontalAlignment = TextAlignmentType.Center;//文字居中
|
|
|
|
// 为合计单元格样式
|
|
Aspose.Cells.Style sumstyle = wb.CreateStyle();
|
|
sumstyle.Font.Size = 12;//文字大小
|
|
sumstyle.Font.IsBold = true;//粗体
|
|
sumstyle.Font.Color = System.Drawing.Color.Red; //颜色
|
|
//style.HorizontalAlignment = TextAlignmentType.Center;//文字居中
|
|
|
|
//添加标题
|
|
int rowIndex = 0;
|
|
sheet.Cells.SetRowHeight(rowIndex, 40); //设置行高
|
|
if (title != null)
|
|
{
|
|
sheet.Cells[rowIndex, 0].PutValue(title);
|
|
sheet.Cells[rowIndex, 0].SetStyle(style);
|
|
sheet.Cells.Merge(0, 0, 1, header.Length); //合并行 Merge(1, 1,1, 5); 第一行 第一列 到 第一行 第 5列
|
|
//Merge切记后两位参数不能是 0
|
|
rowIndex++;
|
|
}
|
|
//添加表头
|
|
style.Font.Size = 12;//文字大小
|
|
sheet.Cells.SetRowHeight(rowIndex, 20); //设置行高
|
|
for (int c = 0; c < header.Length; c++)
|
|
{
|
|
sheet.Cells[rowIndex, c].PutValue(header[c]);
|
|
sheet.Cells[rowIndex, c].SetStyle(style);
|
|
sheet.Cells.SetColumnWidth(c, 20);//设置宽度
|
|
}
|
|
rowIndex++;
|
|
|
|
//添加内容
|
|
for (int r = 0; r < dt.Rows.Count; r++)//遍历DataTable行
|
|
{
|
|
for (int c = 0; c < header.Length; c++) //列只遍历到和表头数量相等的列,其余的列不导出
|
|
{
|
|
//自动把数字变量转出后 单元格变为数字类型。
|
|
try
|
|
{
|
|
//把添加变量转字符类型存储
|
|
sheet.Cells[r + rowIndex, c].PutValue(dt.Rows[r][c].ToString());
|
|
|
|
// sheet.Cells[r + rowIndex, c].PutValue(Convert.ToDecimal(dt.Rows[r][c])); //要导出数字列是数字类型,必须把添加变量转数字类型。
|
|
}
|
|
catch
|
|
{
|
|
//把添加变量转字符类型存储
|
|
sheet.Cells[r + rowIndex, c].PutValue(dt.Rows[r][c].ToString());
|
|
}
|
|
}
|
|
}
|
|
//输出到Excel
|
|
wb.Save(fileName, new OoxmlSaveOptions(SaveFormat.Csv));
|
|
//保存成97或2003写法
|
|
//workbook.Save(“output.xls, New XlsSaveOptions(SaveFormat.Excel97To2003))
|
|
// 释放Excel对象
|
|
sheet.Dispose();
|
|
wb.Dispose();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new ApiResult() { Code = System.Net.HttpStatusCode.NoContent, Message = $"保存{fileName}文件异常:{e.Message}" };
|
|
}
|
|
return new ApiResult();
|
|
}
|
|
|
|
}
|
|
}
|