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(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(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(message, new JsonSerializerOptions { // 整齐打印 WriteIndented = true, //重新编码,解决中文乱码问题 Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }); break; case CSMessage.publish: var publish = JsonSerializer.Deserialize(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 _processDataSource =new ObservableCollection(); public ObservableCollection ProcessDataSource { get { return _processDataSource ; } set { _processDataSource = value; } } private ObservableCollection intervalTimesSource=new ObservableCollection(); public ObservableCollection 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 _apmsProcessSliceSource= new ObservableCollection(); public ObservableCollection ApmsProcessSliceSource { get => _apmsProcessSliceSource; set=> SetProperty(ref _apmsProcessSliceSource, value); } private ObservableCollection _apmsEventSource = new ObservableCollection(); public ObservableCollection ApmsEventSource { get => _apmsEventSource; set => SetProperty(ref _apmsEventSource, value); } private ObservableCollection _toolsProcessSliceSource = new ObservableCollection(); public ObservableCollection ToolsProcessSliceSource { get => _toolsProcessSliceSource; set => SetProperty(ref _toolsProcessSliceSource, value); } private ObservableCollection _toolsEventSource = new ObservableCollection(); public ObservableCollection ToolsEventSource { get => _toolsEventSource; set => SetProperty(ref _toolsEventSource, value); } public static void AddItems(ObservableCollection 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 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 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(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 }); } }); } } } /// /// 启动进程 /// /// /// 进程启动返回值 private int StartProcess(ProcessInfo proInfo) { bool res= CMDStartProcess(proInfo); int seInd = res ? 0 : 37; return seInd; } /// /// 结束进程 /// /// /// 0=成功;1=未找到进程;-1=失败 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; } } /// /// 查找进程 /// /// /// 0=正在运行;1=未运行;-1=系统错误 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 } }