Files
DevToolsAvalonia/常用工具集/ViewModels/02网络相关/端口占用扫描ViewModel.cs
2025-08-26 08:37:44 +08:00

201 lines
7.1 KiB
C#

using Avalonia.Threading;
using MES.Utility.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using .Base;
namespace .ViewModel._02网络相关
{
public class ViewModel : ViewModelBase
{
public bool Enabled1 { get; set; } = true;
public bool Enabled2 { get; set; } = false;
public int SelectedIndex { get; set; } = -1;
public ObservableCollection<ScanResult> DataList { get; set; } = new ObservableCollection<ScanResult>();
public int ProgressValue { get; set; } = 0;
public int ProgressMax { get; set; } = 100;
public DelegateCommand StartScanCmd { get; set; }
public DelegateCommand CloseProcessCmd { get; set; }
public ViewModel()
{
StartScanCmd = new DelegateCommand(StartScanCmdFunc);
CloseProcessCmd = new DelegateCommand(CloseProcessCmdFunc);
}
private void CloseProcessCmdFunc(object obj)
{
if (SelectedIndex < 0)
{
return;
}
int pid = DataList[SelectedIndex].PID;
Process process = Process.GetProcessById(pid);
if (process == null)
{
GlobalValues.Error("获取进程相关信息失败,请尝试重新操作");
return;
}
try
{
process.Kill();
process.WaitForExit();
process.Close();
DataList.RemoveAt(SelectedIndex);
GlobalValues.Success("操作成功");
}
catch (Exception ex)
{
GlobalValues.Error($"结束进程失败:{ex.Message}");
}
}
private void StartScanCmdFunc(object obj)
{
Enabled1 = false;
Enabled2 = false;
ProgressValue = 0;
DataList.Clear();
new Thread(() =>
{
ProcessStartInfo startInfo = new ProcessStartInfo("netstat", "-ano")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
string result = "";
using (Process process = Process.Start(startInfo))
{
using (StreamReader reader = process.StandardOutput)
{
result = reader.ReadToEnd();
}
}
List<string> lines = result.Split('\n').Select(it => it.Trim('\r').Trim()).Where(it => !it.IsNullOrEmpty()).ToList();
List<ScanResult> results = new List<ScanResult>();
foreach (string line in lines)
{
string[] splitArray = line.Split(' ').Where(it => !it.IsNullOrEmpty()).ToArray();
if (!line.StartsWith("TCP") && !line.StartsWith("UDP"))
continue;
if (splitArray.Length == 5)
{
int pid;
bool flag = int.TryParse(splitArray[4], out pid);
if (!flag)
continue;
if (!splitArray[1].Contains(":"))
{
continue;
}
string[] splitArray2 = splitArray[1].Split(':');
int port;
flag = int.TryParse(splitArray2[1], out port);
if (!flag)
continue;
results.Add(new ScanResult
{
Protocol = splitArray[0],
LocalAddress = splitArray[1],
Port = port,
RemoteAddress = splitArray[2],
State = splitArray[3],
PID = pid,
ProcessName = ""
});
}
else if (splitArray.Length == 4)
{
int pid;
bool flag = int.TryParse(splitArray[3], out pid);
if (!flag)
continue;
if (!splitArray[1].Contains(":"))
{
continue;
}
string[] splitArray2 = splitArray[1].Split(':');
int port;
flag = int.TryParse(splitArray2[1], out port);
if (!flag)
continue;
results.Add(new ScanResult
{
Protocol = splitArray[0],
LocalAddress = splitArray[1],
Port = port,
RemoteAddress = splitArray[2],
State = "",
PID = pid,
ProcessName = ""
});
}
}
results = results.OrderBy(it => it.Port).ToList();
Dictionary<int, string> pidName = new Dictionary<int, string>();
foreach (ScanResult scan in results)
{
try
{
if (pidName.ContainsKey(scan.PID))
{
scan.ProcessName = pidName[scan.PID];
}
else
{
Process process = Process.GetProcessById(scan.PID);
if (process != null)
{
pidName.Add(scan.PID, process.ProcessName);
scan.ProcessName = process.ProcessName;
}
}
Dispatcher.UIThread.Invoke(new Action(() =>
{
DataList.Add(scan);
}));
}
catch
{
Dispatcher.UIThread.Invoke(new Action(() =>
{
DataList.Add(scan);
}));
}
}
Dispatcher.UIThread.Invoke(new Action(() =>
{
Enabled1 = true;
Enabled2 = true;
}));
}).Start();
}
}
public class ScanResult
{
public string Protocol { get; set; }
public string LocalAddress { get; set; }
public int Port { get; set; }
public string RemoteAddress { get; set; }
public string State { get; set; }
public int PID { get; set; }
public string ProcessName { get; set; }
}
}