2022-06-10 18:51:48 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net.NetworkInformation;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Windows.Input;
|
2022-06-14 16:40:40 +08:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Windows.Forms;
|
2022-06-30 10:22:12 +08:00
|
|
|
|
using System.Runtime.InteropServices;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
|
|
namespace Topuino_Client_Windows
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Interaction logic for MainWindow.xaml
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class MainWindow : Window
|
|
|
|
|
{
|
|
|
|
|
public MainWindow()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
trayIon.Icon = new Icon(@"Topuino.ico");
|
|
|
|
|
trayIon.Visible = true;
|
|
|
|
|
trayIon.Text = "Topuino";
|
|
|
|
|
trayIon.DoubleClick += TrayIcon_DoubleClick;
|
|
|
|
|
|
2022-06-10 18:51:48 +08:00
|
|
|
|
allDrives = new List<DriveInfo>();
|
|
|
|
|
DriveInfo[] drives = DriveInfo.GetDrives();
|
|
|
|
|
foreach (DriveInfo drive in drives)
|
|
|
|
|
{
|
|
|
|
|
allDrives.Add(drive);
|
|
|
|
|
}
|
|
|
|
|
if (allDrives.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox("找不到可以监控的磁盘");
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ComboBox_Disk0.ItemsSource = allDrives;
|
|
|
|
|
ComboBox_Disk1.ItemsSource = allDrives;
|
|
|
|
|
|
|
|
|
|
if (File.Exists("Config.json"))
|
|
|
|
|
{
|
2022-06-14 16:40:40 +08:00
|
|
|
|
ShowInTaskbar = true;
|
|
|
|
|
Visibility = Visibility.Hidden;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
LoadConfig();
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ApplyConfig();
|
|
|
|
|
StartRun();
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
RadioButton_UsbMode.IsChecked = true;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
ComboBox_Disk0.SelectedIndex = 0;
|
|
|
|
|
ComboBox_Disk1.SelectedIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-14 16:40:40 +08:00
|
|
|
|
private NotifyIcon trayIon = new NotifyIcon();
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
private int mode = 0;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
private string sn = "";
|
|
|
|
|
private List<DriveInfo> allDrives;
|
2022-06-30 10:22:12 +08:00
|
|
|
|
private DriveInfo drive0;
|
|
|
|
|
private DriveInfo drive1;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
|
|
|
|
|
private Thread? refreshThread = null;
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
private ManualResetEvent requestStopEvent = new ManualResetEvent(false);
|
|
|
|
|
private ManualResetEvent stopDoneEvent = new ManualResetEvent(false);
|
2022-06-10 18:51:48 +08:00
|
|
|
|
|
2022-07-02 12:54:24 +08:00
|
|
|
|
private OnlineConnector? onlineConnector = null;
|
|
|
|
|
private UsbConnector? usbConnector = null;
|
2022-06-30 10:22:12 +08:00
|
|
|
|
|
2022-06-10 18:51:48 +08:00
|
|
|
|
private void LoadConfig()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
Config? initConfig = JsonConvert.DeserializeObject<Config>(File.ReadAllText("Config.json"));
|
2022-06-10 18:51:48 +08:00
|
|
|
|
if (initConfig == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception();
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
switch (initConfig.mode)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
RadioButton_UsbMode.IsChecked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
RadioButton_OnlineMode.IsChecked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
RadioButton_LocalMode.IsChecked = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RadioButton_UsbMode.IsChecked = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-10 18:51:48 +08:00
|
|
|
|
// check if drivers missing
|
2022-06-30 10:22:12 +08:00
|
|
|
|
bool disk0Found = false;
|
|
|
|
|
bool disk1Fount = false;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
foreach (DriveInfo drive in allDrives)
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
if (drive.Name == initConfig.disk0)
|
2022-06-10 18:51:48 +08:00
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
disk0Found = true;
|
|
|
|
|
}
|
|
|
|
|
if (drive.Name == initConfig.disk1)
|
|
|
|
|
{
|
|
|
|
|
disk1Fount = true;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-30 10:22:12 +08:00
|
|
|
|
if (!disk0Found)
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox("找不到磁盘0,已切换为默认磁盘");
|
|
|
|
|
initConfig.disk0 = allDrives[0].Name;
|
|
|
|
|
}
|
|
|
|
|
if (!disk1Fount)
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox("找不到磁盘1,已切换为默认磁盘");
|
|
|
|
|
initConfig.disk1 = allDrives[0].Name;
|
|
|
|
|
}
|
2022-06-10 18:51:48 +08:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < allDrives.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (allDrives[i].Name == initConfig.disk0)
|
|
|
|
|
{
|
|
|
|
|
ComboBox_Disk0.SelectedIndex = i;
|
|
|
|
|
}
|
|
|
|
|
if (allDrives[i].Name == initConfig.disk1)
|
|
|
|
|
{
|
|
|
|
|
ComboBox_Disk1.SelectedIndex = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TextBox_DeviceSn.Text = initConfig.sn;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox("初始参数加载错误,请检查配置文件");
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Run()
|
|
|
|
|
{
|
|
|
|
|
PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
|
2022-06-14 15:23:36 +08:00
|
|
|
|
long ramAvailable = PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
|
|
|
|
|
long ramTotal = PerformanceInfo.GetTotalMemoryInMiB();
|
|
|
|
|
long ramPercentFree = ramAvailable * 100 / ramTotal;
|
|
|
|
|
long ramPercentUsed = 100 - ramPercentFree;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
PerformanceCounter diskReadCounter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total");
|
|
|
|
|
PerformanceCounter diskWriteCounter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total");
|
|
|
|
|
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
|
|
|
|
long netBytesSentBefore;
|
|
|
|
|
long netBytesSentAfter;
|
|
|
|
|
long netBytesReceiveBefore;
|
|
|
|
|
long netBytesReceiveAfter;
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
while (!requestStopEvent.WaitOne(0))
|
2022-06-10 18:51:48 +08:00
|
|
|
|
{
|
|
|
|
|
netBytesSentBefore = 0;
|
|
|
|
|
netBytesSentAfter = 0;
|
|
|
|
|
netBytesReceiveBefore = 0;
|
|
|
|
|
netBytesReceiveAfter = 0;
|
|
|
|
|
foreach (NetworkInterface ni in interfaces)
|
|
|
|
|
{
|
|
|
|
|
netBytesSentBefore += ni.GetIPv4Statistics().BytesSent;
|
|
|
|
|
netBytesReceiveBefore += ni.GetIPv4Statistics().BytesReceived;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
|
|
|
|
foreach (NetworkInterface ni in interfaces)
|
|
|
|
|
{
|
|
|
|
|
netBytesSentAfter += ni.GetIPStatistics().BytesSent;
|
|
|
|
|
netBytesReceiveAfter += ni.GetIPStatistics().BytesReceived;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
MonitorData data = new MonitorData
|
|
|
|
|
{
|
|
|
|
|
cpuPercent = (byte)cpuCounter.NextValue(),
|
|
|
|
|
memPercent = (byte)ramPercentUsed,
|
|
|
|
|
disk0Percent = (byte)((double)(drive0.TotalSize - drive0.AvailableFreeSpace) / drive0.TotalSize * 100),
|
|
|
|
|
disk1Percent = (byte)((double)(drive1.TotalSize - drive1.AvailableFreeSpace) / drive1.TotalSize * 100),
|
|
|
|
|
diskReadRate = (uint)diskReadCounter.NextValue(),
|
|
|
|
|
diskWriteRate = (uint)diskWriteCounter.NextValue(),
|
|
|
|
|
netSentRate = (uint)(netBytesSentAfter - netBytesSentBefore),
|
|
|
|
|
netRecvRate = (uint)(netBytesReceiveAfter - netBytesReceiveBefore),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
UsbRun(data);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
OnlineRun(data);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
2022-07-01 17:18:11 +08:00
|
|
|
|
LocalRun(data);
|
2022-06-30 10:22:12 +08:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
stopDoneEvent.Set();
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
private void UsbRun(MonitorData data)
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
if (usbConnector == null)
|
2022-07-01 17:18:11 +08:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
usbConnector = new UsbConnector();
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ShowConnected();
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
usbConnector = null;
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ShowDisconnected();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
int size = Marshal.SizeOf(data);
|
|
|
|
|
byte[] bin = new byte[size];
|
|
|
|
|
IntPtr ptr = IntPtr.Zero;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ptr = Marshal.AllocHGlobal(size);
|
|
|
|
|
Marshal.StructureToPtr(data, ptr, true);
|
|
|
|
|
Marshal.Copy(ptr, bin, 0, size);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
usbConnector.Send(bin);
|
2022-07-01 17:18:11 +08:00
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
usbConnector.Dispose();
|
|
|
|
|
usbConnector = null;
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ShowDisconnected();
|
|
|
|
|
}
|
2022-06-30 10:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnlineRun(MonitorData data)
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
if (onlineConnector == null)
|
2022-07-01 17:18:11 +08:00
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
onlineConnector = new OnlineConnector();
|
2022-07-01 17:18:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
Dictionary<string, string> statusInfo = new Dictionary<string, string>();
|
|
|
|
|
statusInfo.Add("SN", sn);
|
|
|
|
|
statusInfo.Add("CPU_PERCENT", data.cpuPercent.ToString());
|
|
|
|
|
statusInfo.Add("MEM_PERCENT", data.memPercent.ToString());
|
|
|
|
|
statusInfo.Add("DISK_PERCENT", data.disk0Percent.ToString());
|
|
|
|
|
statusInfo.Add("DISK1_PERCENT", data.disk1Percent.ToString());
|
|
|
|
|
statusInfo.Add("DISK_READ_RATE", data.diskReadRate.ToString());
|
|
|
|
|
statusInfo.Add("DISK_WRITE_RATE", data.diskWriteRate.ToString());
|
|
|
|
|
statusInfo.Add("NET_SENT_RATE", data.netSentRate.ToString());
|
|
|
|
|
statusInfo.Add("NET_RECV_RATE", data.netRecvRate.ToString());
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
onlineConnector.Post(statusInfo).Wait();
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ShowConnected();
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
onlineConnector.Dispose();
|
|
|
|
|
onlineConnector = null;
|
2022-07-01 17:18:11 +08:00
|
|
|
|
ShowDisconnected();
|
|
|
|
|
}
|
2022-06-30 10:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
private void LocalRun(MonitorData data)
|
2022-06-30 10:22:12 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-06-10 18:51:48 +08:00
|
|
|
|
public void ShowErrorBox(string msg)
|
|
|
|
|
{
|
2022-06-14 16:40:40 +08:00
|
|
|
|
System.Windows.MessageBox.Show(
|
|
|
|
|
System.Windows.Application.Current.MainWindow,
|
2022-06-10 18:51:48 +08:00
|
|
|
|
msg,
|
|
|
|
|
"错误",
|
|
|
|
|
MessageBoxButton.OK,
|
|
|
|
|
MessageBoxImage.Error
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ApplyConfig()
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (RadioButton_UsbMode.IsChecked == true)
|
|
|
|
|
{
|
|
|
|
|
mode = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (RadioButton_OnlineMode.IsChecked == true)
|
|
|
|
|
{
|
|
|
|
|
mode = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (RadioButton_LocalMode.IsChecked == true)
|
|
|
|
|
{
|
|
|
|
|
mode = 2;
|
|
|
|
|
}
|
|
|
|
|
sn = TextBox_DeviceSn.Text;
|
|
|
|
|
|
|
|
|
|
drive0 = ComboBox_Disk0.SelectedItem as DriveInfo;
|
|
|
|
|
drive1 = ComboBox_Disk1.SelectedItem as DriveInfo;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox(e.Message);
|
|
|
|
|
}
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartRun()
|
|
|
|
|
{
|
|
|
|
|
if (!drive0.IsReady || !drive1.IsReady)
|
|
|
|
|
{
|
|
|
|
|
ShowErrorBox("磁盘未就绪");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
refreshThread = new Thread(Run);
|
|
|
|
|
refreshThread.Start();
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-30 10:22:12 +08:00
|
|
|
|
private void StopRun()
|
|
|
|
|
{
|
|
|
|
|
if (refreshThread != null)
|
|
|
|
|
{
|
2022-07-01 17:18:11 +08:00
|
|
|
|
requestStopEvent.Set();
|
|
|
|
|
stopDoneEvent.WaitOne();
|
2022-06-30 10:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
refreshThread = null;
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
requestStopEvent.Reset();
|
|
|
|
|
stopDoneEvent.Reset();
|
2022-06-30 10:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-10 18:51:48 +08:00
|
|
|
|
private async void SaveConfig()
|
|
|
|
|
{
|
|
|
|
|
Config newConfig = new Config();
|
2022-06-30 10:22:12 +08:00
|
|
|
|
newConfig.mode = mode;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
newConfig.sn = sn;
|
|
|
|
|
newConfig.disk0 = drive0.Name;
|
|
|
|
|
newConfig.disk1 = drive1.Name;
|
|
|
|
|
await File.WriteAllTextAsync("Config.json", JsonConvert.SerializeObject(newConfig, Formatting.Indented));
|
2022-06-30 10:22:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ResetConnectors()
|
|
|
|
|
{
|
2022-07-02 12:54:24 +08:00
|
|
|
|
usbConnector?.Dispose();
|
|
|
|
|
onlineConnector?.Dispose();
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Button_Save_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
|
|
|
|
|
StopRun();
|
|
|
|
|
ResetConnectors();
|
2022-06-10 18:51:48 +08:00
|
|
|
|
ApplyConfig();
|
|
|
|
|
SaveConfig();
|
|
|
|
|
StartRun();
|
2022-06-30 10:22:12 +08:00
|
|
|
|
Mouse.OverrideCursor = null;
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
2022-06-14 16:40:40 +08:00
|
|
|
|
|
|
|
|
|
private void TrayIcon_DoubleClick(object? sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Visibility = Visibility.Visible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Button_Hide_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Visibility = Visibility.Hidden;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 17:18:11 +08:00
|
|
|
|
private void ShowConnected()
|
|
|
|
|
{
|
|
|
|
|
if (requestStopEvent.WaitOne(0))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() => {
|
|
|
|
|
TextBlock_Status.Text = "已连接";
|
|
|
|
|
TextBlock_Status.Foreground = System.Windows.Media.Brushes.Green;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ShowDisconnected()
|
|
|
|
|
{
|
|
|
|
|
if (requestStopEvent.WaitOne(0))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() => {
|
|
|
|
|
TextBlock_Status.Text = "未连接";
|
|
|
|
|
TextBlock_Status.Foreground = System.Windows.Media.Brushes.Red;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-14 16:40:40 +08:00
|
|
|
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
|
|
|
|
{
|
2022-06-30 10:22:12 +08:00
|
|
|
|
StopRun();
|
|
|
|
|
ResetConnectors();
|
2022-06-14 16:40:40 +08:00
|
|
|
|
}
|
2022-06-10 18:51:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|