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.

825 lines
31 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using K4os.Compression.LZ4.Engine;
using Org.BouncyCastle.Crypto.Modes;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using StartServerWPF.Assets;
using StartServerWPF.Modules.Main.models;
using StartServerWPF.Modules.Main.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace StartServerWPF.Modules.Main.ViewModels
{
public class MainViewModel : BindableBase
{
public MainViewModel(IDialogService dialogService, WebsocketClient websocket, LoginViewDialogViewModel loginViewDialogViewModel)
{
Message = "View A" ;
Console.WriteLine(System.Environment.CurrentDirectory + "\\" + JsonParser.systemConfigPath);
sc = JsonParser.ReadSystemJsonFile(JsonParser.systemConfigPath);
// int moniTimeInd = sc.proMonitor.ProParams.IndexOf("-btime");
// string moniTimeStr = sc.proMonitor.ProParams.Substring(moniTimeInd + 7);
// int moniTimeIndEnd = moniTimeStr.IndexOf(">");
//moniTimeStr = moniTimeStr.Substring(0, moniTimeIndEnd - 1);
// MoniStartTime = DateTime.Parse(moniTimeStr);
InitializeParams();
JsonParser.UpdateApmsJson(sc.proApms.ProPath + "apms.json", sc.vpnInfo.DataSavePath);
JsonParser.UpdateRecvJson(sc.proRecv.ProPath + "gw.recvftp.json", sc.vpnInfo.DataSavePath);
// sc.proMonitor.ProParams = JsonParser.CreateMonitorStartParam(sc.vpnInfo.DataSavePath, MoniStartTime);
StartTime = DateTime.Now;
Console.WriteLine(System.Environment.CurrentDirectory);
Console.WriteLine(sc.remoteDb.ServerAddress + "\t" + sc.remoteDb.ServerPort
+ "\t" + sc.remoteDb.UserName + "\t" + sc.remoteDb.Password);
this._dialogService = dialogService;
this._websocket = websocket;
this._loginViewDialogViewModel = loginViewDialogViewModel;
_websocket.WebSocketInit(sc.remoteDb.WebsocketUrl);
_websocket.WebsocketError = WebSocket_Error;
_websocket.WebSocketMessageReceived = WebSocket4Net_MessageReceived;
DialogParameters param = new DialogParameters();
param.Add("type", 1);// 编辑
_dialogService.ShowDialog(
"LoginViewDialog",
param,
new Action<IDialogResult>(result =>
{
if (result != null && result.Result == ButtonResult.OK)
{
IntilVPN();
SetControlstatus();
}
else
{
Environment.Exit(0);
}
}));
}
private void WebSocket4Net_MessageReceived(string message)
{
Debug.WriteLine($"服务端回复数据:{message}");
using (JsonDocument document = JsonDocument.Parse(message))
{
JsonElement root = document.RootElement;
if (root.TryGetProperty("type", out JsonElement dataElement))
{
string type = dataElement.ToString();
switch (type)
{
case CSMessage.sigin:
var user = JsonSerializer.Deserialize<SCUserSigin>(message, new JsonSerializerOptions
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
_loginViewDialogViewModel.OnShowLoading(new LoadingPayload { IsShow = false });
Application.Current.Dispatcher.Invoke(() =>
{
HandyControl.Controls.MessageBox.Show(user.message, "提示");
if (user.code == 200)
{
_websocket.SendMes(JsonSerializer.Serialize(new CSUserSubscribeMessage { type = CSMessage.subscribe }));
_loginViewDialogViewModel.CloseDialog(new DialogResult(ButtonResult.OK));
var log = new LogMessageModel
{
LogType = "系统",
AppName = "系统",
State = user.account+ "登录",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath, log.ToString());
}
});
break;
case CSMessage.subscribe:
var sub = JsonSerializer.Deserialize<SCUserSubscribeMessage>(message, new JsonSerializerOptions
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
break;
case CSMessage.publish:
var publish = JsonSerializer.Deserialize<SCDevicePublish>(message, new JsonSerializerOptions
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
var data= ApmsEventSource.Where(e => e.ToString() == publish.message).FirstOrDefault();
if (data!=null)
{
data.IsSend = true;
}
break;
default:
break;
}
}
}
}
void WebSocket_Error(SuperSocket.ClientEngine.ErrorEventArgs e)
{
_loginViewDialogViewModel.OnShowLoading(new LoadingPayload { IsShow = false });
//出错后隐藏加载窗口
Debug.WriteLine("websocket_Error:" + e.Exception.ToString());
}
#region 属性
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
private DateTime startTime;
private DateTime moniStartTime;
public DateTime StartTime { get => startTime; set => SetProperty(ref startTime, value); }
public DateTime MoniStartTime { get => moniStartTime; set => SetProperty(ref moniStartTime, value); }
private string runTime;
public string RunTime
{
get { return runTime; }
set { SetProperty(ref runTime, value); }
}
private string vPNStatus;
public string VPNStatus
{
get { return vPNStatus; }
set { SetProperty(ref vPNStatus, value);
}
}
private string vpnIP;
public string VpnIP
{
get { return vpnIP; }
set { SetProperty(ref vpnIP, value); }
}
private string vPNStatusForeColor;
public string VPNStatusForeColor
{
get { return vPNStatusForeColor; }
set { SetProperty(ref vPNStatusForeColor, value); }
}
private bool vPNIsConnect;
public bool VPNIsConnect
{
get { return vPNIsConnect; }
set { SetProperty(ref vPNIsConnect, value); }
}
private bool isIndeterminate=false;
public bool IsIndeterminate
{
get { return isIndeterminate; }
set { SetProperty(ref isIndeterminate, value); }
}
private ObservableCollection<ProcessModel> _processDataSource =new ObservableCollection<ProcessModel>();
public ObservableCollection<ProcessModel> ProcessDataSource
{
get { return _processDataSource ; }
set { _processDataSource = value; }
}
private ObservableCollection<int> intervalTimesSource=new ObservableCollection<int>();
public ObservableCollection<int> IntervalTimesSource
{
get { return intervalTimesSource; }
set { intervalTimesSource = value; }
}
private int selectedIndex;
public int SelectedIndex
{
get { return selectedIndex; }
set { SetProperty(ref selectedIndex, value); }
}
private int proMonInterval = 10;
public int ProMonInterval { get => proMonInterval;
set => SetProperty(ref proMonInterval, value);
}
private ObservableCollection<ProcessingInformationModel> _apmsProcessSliceSource= new ObservableCollection<ProcessingInformationModel>();
public ObservableCollection<ProcessingInformationModel> ApmsProcessSliceSource
{
get => _apmsProcessSliceSource;
set=> SetProperty(ref _apmsProcessSliceSource, value);
}
private ObservableCollection<MsEventModel> _apmsEventSource = new ObservableCollection<MsEventModel>();
public ObservableCollection<MsEventModel> ApmsEventSource
{
get => _apmsEventSource;
set => SetProperty(ref _apmsEventSource, value);
}
private ObservableCollection<ProcessingInformationModel> _toolsProcessSliceSource = new ObservableCollection<ProcessingInformationModel>();
public ObservableCollection<ProcessingInformationModel> ToolsProcessSliceSource
{
get => _toolsProcessSliceSource;
set => SetProperty(ref _toolsProcessSliceSource, value);
}
private ObservableCollection<MsEventModel> _toolsEventSource = new ObservableCollection<MsEventModel>();
public ObservableCollection<MsEventModel> ToolsEventSource
{
get => _toolsEventSource;
set => SetProperty(ref _toolsEventSource, value);
}
public static void AddItems<T>(ObservableCollection<T> list, T t1)
{
if (list == null)
{
return;
}
list.Add(t1);
if (list.Count > 30)
{
T item = list[0];
list.RemoveAt(0);
}
}
#endregion
#region 事件
public DelegateCommand LoadedCommand => new(Loaded);
public DelegateCommand UnloadedCommand => new(Unloaded);
public DelegateCommand<object> ConnectVPNCommand => new(ConnectVPN);
public DelegateCommand DisConnectVPNCommand => new(DisConnectVPN);
public DelegateCommand GetVPNStatusCommand => new(GetVPNStatus);
public DelegateCommand SetVPNParaCommand => new(SetVPNPara);
public DelegateCommand DisplayLogCommand => new(DisplayLog);
public DelegateCommand<object> StartCommand => new(Start);
// public DelegateCommand OneKeyStopCommand => new(OneKeyStop);
private void Loaded()
{
}
public void Unloaded()
{
}
private void ConnectVPN(object obj)
{
var cBox = obj as CheckBox;
if ((bool)cBox.IsChecked)
{
ConnectVPN();
}
else
{
DisConnectVPN();
}
}
private void ConnectVPN()
{
vpn.CreateOrUpdateVPN(sc.vpnInfo.VpnName, sc.vpnInfo.VpnIP);
vpn.ConnectVPN(sc.vpnInfo.VpnName, sc.vpnInfo.VpnUserName, sc.vpnInfo.VpnPsw);
Thread.Sleep(1000);
var log = new LogMessageModel
{
LogType="网络",
AppName="VPN",
State="连接",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
SetControlstatus();
}
private void DisConnectVPN()
{
if (MessageBox.Show("是否断开VPN连接", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
{
vpn.DisConnectVPN(sc.vpnInfo.VpnName);
Thread.Sleep(500);
SetControlstatus();
Thread.Sleep(100);
var log = new LogMessageModel
{
LogType = "网络",
AppName = "VPN",
State = "断开",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
}
}
private void GetVPNStatus()
{
if (vpn.CheckVpnStatus(sc.vpnInfo.VpnName))
{
MessageBox.Show("VPN已经连接!");
}
else
{
MessageBox.Show("VPN断开连接!");
}
}
private void SetVPNPara()
{
DialogParameters param = new DialogParameters();
param.Add("type", 1);// 编辑
param.Add("model", sc);
param.Add("moniTime", MoniStartTime);
_dialogService.ShowDialog(
"SetParamDialog",
param,
new Action<IDialogResult>(result =>
{
if (result != null && result.Result == ButtonResult.OK)
{
MessageBox.Show("数据已保存", "提示");
}
}));
}
private void DisplayLog()
{
Process.Start("explorer.exe", sc.vpnInfo.SystemLogPath);
}
private void Start( object obj)
{
var cBox = obj as CheckBox;
if((bool)cBox.IsChecked)
{
OneKeyStart();
}
else
{
OneKeyStop();
}
}
private void OneKeyStart()
{
ProcessDataSource.Clear();
foreach (var item in sc.GetType().GetProperties())
{
var pro = item.GetValue(sc) as ProcessInfo;
if (pro != null)
{
StartTime = DateTime.Now;
pro.Pid= StartProcess(pro);
ProcessDataSource.Add(new ProcessModel
{
ProName = pro.ProName,
ProcessTile = pro.ProTitle,
MonitorTime = DateTime.Now.ToString(),
ProcessStatus = sc.proServer.Pid == 0 ? "正常运行" : "未运行"
}) ;
Thread.Sleep(10);
}
}
RunTime = DateDiff(DateTime.Now, StartTime);
var log = new LogMessageModel
{
LogType = "系统",
AppName = "系统",
State = "启动服务程序",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
IsIndeterminate =true;
timer1.Interval = TimeSpan.FromSeconds(ProMonInterval);
timer1.Start();
}
public void OneKeyStop()
{
foreach (var item in sc.GetType().GetProperties())
{
var pro = item.GetValue(sc) as ProcessInfo;
if (pro != null)
{
int indexPro = KillProcess(pro);
var model= ProcessDataSource.Where(x => x.ProName == pro.ProName).FirstOrDefault();
if (model == null) continue;
model.MonitorTime= DateTime.Now.ToString();
model.ProcessStatus = "已停止";
}
}
timer1.Stop();
IsIndeterminate = false;
var log = new LogMessageModel
{
LogType = "系统",
AppName = "系统",
State = "启动服务关闭",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
StartTime = new DateTime();
}
#endregion
private void ConnectVpn()
{
// 系统路径 C:\windows\system32\
string WinDir = Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) + @"";
Console.WriteLine(WinDir);
// rasdial.exe
string RasDialFileName = "rasdial.exe";
// VPN路径 C:\windows\system32\rasdial.exe
string VPNPROCESS = WinDir + "\\" + RasDialFileName;
// VPN地址
//string IPToPing = "49.232.209.49";
// VPN名称
string VPNName = "余吾手动";
// VPN用户名
string UserName = "lzvpn";
// VPN密码
string PassWord = "Lz123456789";
string args = string.Format("{0} {1} {2}", VPNName, UserName, PassWord);
ProcessStartInfo myProcess = new ProcessStartInfo(VPNPROCESS, args);
myProcess.CreateNoWindow = true;
myProcess.UseShellExecute = false;
Process.Start(myProcess);
}
private void IntilVPN()
{
vpn = new VPNHelper(sc.vpnInfo.VpnName, sc.vpnInfo.VpnIP, sc.vpnInfo.VpnUserName, sc.vpnInfo.VpnPsw);
}
[DllImport("shell32.dll")]
public static extern int ShellExecute(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int FsShowCmd);
public VPNHelper vpn;
public bool vpnStatus = false;
public SystemConfig sc;
private DispatcherTimer timer1= new DispatcherTimer();
private readonly IDialogService _dialogService;
private readonly WebsocketClient _websocket;
private readonly LoginViewDialogViewModel _loginViewDialogViewModel;
public void InitializeParams()
{
timer1.Interval = TimeSpan.FromSeconds(ProMonInterval);
timer1.Tick += timer1_Tick;
this.Message = "服务器版本:" + JsonParser.serverVision;
IntervalTimesSource.Add(5);
IntervalTimesSource.Add(10);
IntervalTimesSource.Add(15);
IntervalTimesSource.Add(20);
IntervalTimesSource.Add(30);
IntervalTimesSource.Add(60);
SelectedIndex = 1;
var log = new LogMessageModel
{
LogType = "系统",
AppName = "系统",
State = "程序启动",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
}
#region 方法
private bool CMDStartProcess(ProcessInfo proInfo)
{
//* Create your Process
Process process = new Process();
process.Exited += Process_Exited;
process.EnableRaisingEvents = true;
process.StartInfo.FileName = Path.GetFullPath(proInfo.ProPath + proInfo.ProName+".exe");
process.StartInfo.WorkingDirectory = Path.GetFullPath(proInfo.ProPath);
process.StartInfo.Arguments = proInfo.ProParams;
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)
{
Application.Current.Dispatcher.BeginInvoke(() =>
{
if (pro.MainModule.ModuleName.Contains(sc.proApms.ProName))
{
AddItems(ApmsProcessSliceSource, new ProcessingInformationModel { ProcessMes = outLine.Data, MonitorTime = DateTime.Now.ToString() });
}
else if (pro.MainModule.ModuleName.Contains(sc.proTools.ProName))
{
AddItems(ToolsProcessSliceSource, new ProcessingInformationModel { ProcessMes = outLine.Data, MonitorTime = DateTime.Now.ToString() });
}
});
}
}
else if (outLine.Data.Contains("ML "))
{
var pro = sendingProcess as Process;
if (pro != null)
{
Application.Current.Dispatcher.BeginInvoke(() =>
{
if (pro.MainModule.ModuleName.Contains(sc.proApms.ProName))
{
var ms = new MsEventModel(outLine.Data) { CurrentTime = DateTime.Now };
AddItems(ApmsEventSource, ms);
var data = ApmsEventSource.Where(f => f.OriginTime == ms.OriginTime).FirstOrDefault();
if (data == null)
{
CSDevicePublish cSDevicePublish = new CSDevicePublish()
{
type = CSMessage.publish,
message = outLine.Data,
};
string jsonStr = JsonSerializer.Serialize(cSDevicePublish);
_websocket.SendMes(jsonStr);
}
}
else if (pro.MainModule.ModuleName.Contains(sc.proTools.ProName))
{
AddItems(ToolsEventSource, new MsEventModel(outLine.Data) { CurrentTime = DateTime.Now });
}
});
}
}
}
/// <summary>
/// 启动进程
/// </summary>
/// <param name="proInfo"></param>
/// <returns>进程启动返回值</returns>
private int StartProcess(ProcessInfo proInfo)
{
bool res= CMDStartProcess(proInfo);
int seInd = res ? 0 : 37;
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)
{
Console.WriteLine(item.Id);
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;
}
return ri;
}
catch (Exception)
{
return -1;
}
}
private string DateDiff(DateTime DateTime1, DateTime DateTime2)
{
string dateDiff = null;
TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
TimeSpan ts2 = new
TimeSpan(DateTime2.Ticks);
TimeSpan ts = ts1.Subtract(ts2).Duration();
if (ts.Days > 0)
{
dateDiff += ts.Days.ToString() + "天";
}
if (ts.Hours > 0)
{
dateDiff += ts.Hours.ToString() + "小时";
}
if (ts.Minutes > 0)
{
dateDiff += ts.Minutes.ToString() + "分钟";
}
dateDiff += ts.Seconds.ToString() + "秒";
return dateDiff;
}
private void timer1_Tick(object? sender, EventArgs e)
{
foreach (var item in sc.GetType().GetProperties())
{
var pro = item.GetValue(sc) as ProcessInfo;
if (pro != null)
{
int sfp = FindProcess(pro);
var model = ProcessDataSource.Where(x => x.ProName == pro.ProName).FirstOrDefault();
if (sfp == 0)
{
model.ProcessStatus = "正常运行";
}
else
{
model.ProcessStatus = "重启中";
Thread.Sleep(2);
StartProcess(pro);
Thread.Sleep(20);
var log = new LogMessageModel
{
LogType = "应用",
AppName = pro.ProName,
State = "重启",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
string jsonStr= JsonSerializer.Serialize(new CSDeviceWebhook
{
type= CSMessage.webhook,
message = log.ToString(),
}, new JsonSerializerOptions
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
_websocket.SendMes(jsonStr);
}
}
}
RunTime = DateDiff(DateTime.Now, StartTime);
vpnStatus = vpn.CheckVpnStatus(sc.vpnInfo.VpnName);
if (!vpnStatus)
{
vpn.ConnectVPN(sc.vpnInfo.VpnName, sc.vpnInfo.VpnUserName, sc.vpnInfo.VpnPsw);
Thread.Sleep(1000);
var log = new LogMessageModel
{
LogType = "应用",
AppName = "VPN",
State = "重连",
OriginTime = DateTime.Now,
};
LogHelper.WriteSerLog(sc.vpnInfo.SystemLogPath , log.ToString());
string jsonStr = JsonSerializer.Serialize(new CSDeviceWebhook
{
type = CSMessage.webhook,
message = log.ToString(),
}, new JsonSerializerOptions
{
// 整齐打印
WriteIndented = true,
//重新编码,解决中文乱码问题
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
});
_websocket.SendMes(jsonStr);
}
}
public void GetLocalIp()
{
///获取本地的IP地址
string AddressIP = string.Empty;
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
{
AddressIP = _IPAddress.ToString();
if (AddressIP.Contains("172.16"))
{
sc.vpnInfo.VpnIP = AddressIP;
}
}
}
}
public void SetControlstatus()
{
vpnStatus = vpn.CheckVpnStatus(sc.vpnInfo.VpnName);
if (vpnStatus)
{
VPNIsConnect = true;
VPNStatusForeColor = "#FF008000";
VPNStatus = "VPN已连接";
VpnIP = vpn.GetLocalIp();
}
else
{
VPNIsConnect = false;
VPNStatusForeColor = "#FFFF0000";
VPNStatus = "VPN断开连接";
}
}
#endregion
}
}