A:增加PID单独信息获取;增加进程信息获取函数

This commit is contained in:
jimmy committed 2025-07-03 15:13:10 +08:00
1 parent d1ecd6b6e2
commit 095783ea61
4 files changed
+246 -21

No files matched your search

@@ -17,7 +17,7 @@ public sealed class ProcessCache
var process = Process.GetProcessById(pid);
return $"{pid}-{process.StartTime:yyyyMMddHHmmss}";
}
// 私有构造函数,禁止外部创建实例
private ProcessCache()
{
@@ -27,14 +27,17 @@ public sealed class ProcessCache
/// <summary>
/// 缓存字典【给定初始量 1000 ,后期可根据需求调整,避免频繁扩容】
/// </summary>
private readonly Dictionary<string, ProgramInfo> _cache = new(1000);
private readonly Dictionary<string, CacheItem> _cache = new(1000);
// 设置缓存
public void Set(string key, ProgramInfo value)
{
lock (_cache)
{
_cache[key] = value;
_cache[key] = new CacheItem
{
Info = value
};
}
}
@@ -43,7 +46,16 @@ public sealed class ProcessCache
{
lock (_cache)
{
return _cache.GetValueOrDefault(key);
if (_cache.TryGetValue(key, out var item))
{
if ((DateTime.Now - item.TimeStamp).TotalMinutes < 2)
return item.Info;
// 超时,移除
_cache.Remove(key);
}
return null;
}
}
@@ -56,9 +68,15 @@ public sealed class ProcessCache
}
}
}
public class CacheItem
{
public required ProgramInfo Info { get; init; }
public DateTime TimeStamp { get; init; } = DateTime.Now;
}
/*
PID 重用问题:
🧠 背景 recap:
操作系统(如 Windows)中的每个连接通常可以获取一个 PID。
但由于:
@@ -77,5 +95,5 @@ public sealed class ProcessCache
但 PID 对应的进程启动时间是 18:10
→ 说明这个进程是后来启动的(PID 被重用了)
→ ❌ 不应该关联这条连接
*/
*/
+111 -14
View File
@@ -14,6 +14,7 @@ using Common.Logger;
using Common.Net.HttpConn;
using Common.Net.Models;
using Common.Net.WebSocketConn;
using Common.Utils;
using Microsoft.Extensions.Logging;
using Serilog.Events;
using Utils.ETW.Etw;
@@ -135,11 +136,16 @@ public partial class App : System.Windows.Application
// 订阅 websocket 关闭服务
WebSocketManager.Instance.SubscribeConnectionClosed((args =>
{
if (args.Uuid != null) DispatchEngine.Instance.DeleteApplicationInfo(args.Uuid);
if (args.Uuid != null)
{
DispatchEngine.Instance.DeleteApplicationInfo(args.Uuid);
DispatchEngine.Instance.DeleteProcessInfo(args.Uuid);
}
}
));
// 开启 WebSocket 定时发送服务
DispatchEngine.Instance.ApplicationInfoDistribute();
DispatchEngine.Instance.ProcessInfoDistribute();
// 启动 http 服务
Task.Run(() => { _ = StartHttpServer(); });
@@ -174,8 +180,9 @@ public partial class App : System.Windows.Application
server.Get("/api",
async (context) => { await context.Response.WriteJsonAsync(new { message = "Hi!" }); });
// 订阅某信息
server.Post("/api/subscribe", async (context) =>
#region 软件信息订阅
server.Post("/api/subscribe-application", async (context) =>
{
// 正确的做法:只处理请求体数据
if (string.IsNullOrEmpty(context.RequestBody))
@@ -199,18 +206,27 @@ public partial class App : System.Windows.Application
string? uuid = context.Request.Headers["uuid"];
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
var subscriptionInfo = JsonSerializer.Deserialize<SubscriptionInfo>(requestData);
if (subscriptionInfo != null && !string.IsNullOrWhiteSpace(uuid))
if (string.IsNullOrWhiteSpace(uuid))
{
if (AppConfig.ApplicationInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
context.Response.StatusCode = 400;
await context.Response.WriteJsonAsync(new ResponseModel<object>
{
DispatchEngine.Instance.AddApplicationInfo(uuid, new DispatchModel
{
Interval = subscriptionInfo.Interval
});
}
Success = false,
Message = $"用户 ID 丢失!",
});
return;
}
var subscriptionInfo = JsonHelper.FromJson<SubscriptionInfo>(requestData);
if (subscriptionInfo != null)
{
// 软件信息订阅
DispatchEngine.Instance.AddApplicationInfo(uuid, new DispatchModel
{
Interval = subscriptionInfo.Interval
});
Log.Warning($"名称: {subscriptionInfo.SubscriptionType}");
Log.Warning($"时间: {subscriptionInfo.Interval}");
}
}
@@ -235,7 +251,81 @@ public partial class App : System.Windows.Application
});
});
// 取消订阅
#endregion
#region 线程信息订阅
server.Post("/api/subscribe-process", async (context) =>
{
if (string.IsNullOrEmpty(context.RequestBody))
{
context.Response.StatusCode = 400;
await context.Response.WriteJsonAsync(new ResponseModel<object>
{
Success = false,
Message = "请求体不能为空",
});
return;
}
// 解析请求数据
try
{
string requestData = context.RequestBody;
// 打印原始数据用于调试
string? uuid = context.Request.Headers["uuid"];
if (string.IsNullOrWhiteSpace(uuid))
{
context.Response.StatusCode = 400;
await context.Response.WriteJsonAsync(new ResponseModel<object>
{
Success = false,
Message = $"用户 ID 丢失!",
});
return;
}
var subscriptionInfo = JsonHelper.FromJson<SubscriptionProcessInfo>(requestData);
if (subscriptionInfo != null)
{
DispatchEngine.Instance.DeleteProcessInfo(uuid);
DispatchEngine.Instance.AddProcessInfo(uuid, new ProcessDispatchModel
{
Interval = subscriptionInfo.Interval,
ProcessIds = subscriptionInfo.ProcessIds
});
Log.Warning($"时间: {subscriptionInfo.Interval}");
Log.Warning($"监视的 ID : {subscriptionInfo.ProcessIds}");
}
}
catch (JsonException ex)
{
context.Response.StatusCode = 400;
await context.Response.WriteJsonAsync(new ResponseModel<object>
{
Success = false,
Message = $"请求数据格式错误: {ex.Message}",
});
return;
}
// 返回响应 - 只序列化纯数据对象
context.Response.StatusCode = 200;
await context.Response.WriteJsonAsync(new ResponseModel<string>
{
Success = true,
Data = "成功",
Message = "订阅成功",
});
});
#endregion
#region 取消订阅
server.Post("/api/unsubscribe", async (context) =>
{
// 正确的做法:只处理请求体数据
@@ -260,13 +350,19 @@ public partial class App : System.Windows.Application
string? uuid = context.Request.Headers["uuid"];
Log.Warning($"接收到的数据: {requestData}, 用户 Id: {uuid}");
var subscriptionInfo = JsonSerializer.Deserialize<SubscriptionInfo>(requestData);
var subscriptionInfo = JsonHelper.FromJson<SubscriptionInfo>(requestData);
if (subscriptionInfo != null && !string.IsNullOrWhiteSpace(uuid))
{
// 软件信息订阅
if (AppConfig.ApplicationInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
{
DispatchEngine.Instance.DeleteApplicationInfo(uuid);
}
// 进程信息订阅
else if (AppConfig.ProcessInfoSubscribe.Equals(subscriptionInfo.SubscriptionType))
{
DispatchEngine.Instance.DeleteProcessInfo(uuid);
}
Log.Warning($"取消订阅的 名称: {subscriptionInfo.SubscriptionType}");
}
@@ -292,6 +388,7 @@ public partial class App : System.Windows.Application
});
});
#endregion
// 启动服务器
try
@@ -27,6 +27,87 @@ public class ProcessNetworkInfo
public List<string> ActiveConnections { get; set; } = new List<string>();
}
/// <summary>
/// 进程信息
/// </summary>
public class ProcessType
{
/// <summary>
/// 进程名称
/// </summary>
public string ProcessName { get; set; }
/// <summary>
/// 进程ID
/// </summary>
public int ProcessId { get; set; }
/// <summary>
/// 启动时间
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 是否退出
/// </summary>
public bool HasExited { get; set; }
/// <summary>
/// 退出时间
/// </summary>
public DateTime? ExitTime { get; set; }
/// <summary>
/// 退出代码
/// </summary>
public int? ExitCode { get; set; }
/// <summary>
/// 占用内存
/// </summary>
public long UseMemory { get; set; }
/// <summary>
/// 线程数
/// </summary>
public int ThreadCount { get; set; }
/// <summary>
/// 主模块路径
/// </summary>
public string? MainModulePath { get; set; }
/// <summary>
/// 启动文件名
/// </summary>
public string? MainModuleName { get; set; }
/// <summary>
/// 上行总量
/// </summary>
public long TotalUploaded { get; set; }
/// <summary>
/// 下行总量
/// </summary>
public long TotalDownloaded { get; set; }
/// <summary>
/// 上行速度
/// </summary>
public double UploadSpeed { get; set; }
/// <summary>
/// 下行速度
/// </summary>
public double DownloadSpeed { get; set; }
/// <summary>
/// 所有连接
/// </summary>
public List<ConnectionInfo> Connections { get; set; } = new List<ConnectionInfo>();
}
/// <summary>
/// 连接详细信息
/// </summary>
@@ -35,14 +116,17 @@ public class ConnectionInfo
public string ConnectionKey { get; set; }
public int ProcessId { get; set; }
public ProtocolType Protocol { get; set; }
/// <summary>
/// 本地 终结点
/// </summary>
public IPEndPoint LocalEndpoint { get; set; }
/// <summary>
/// 目标 终结点
/// </summary>
public IPEndPoint RemoteEndpoint { get; set; }
public ConnectionState State { get; set; }
public TrafficDirection Direction { get; set; }
public DateTime StartTime { get; set; }
@@ -138,10 +222,12 @@ public class ConnectionSnapshot
public int RemotePort { get; set; }
public string RemoteDomain { get; set; }
public string State { get; set; }
/// <summary>
/// 方向
/// </summary>
public string Direction { get; set; }
public DateTime StartTime { get; set; }
public TimeSpan Duration { get; set; }
public long BytesSent { get; set; }
@@ -390,6 +390,30 @@ public sealed class GlobalNetworkMonitor
return _applications.Values.ToList().Select(applicationInfo => applicationInfo.ProgramInfo).ToList();
}
/// <summary>
/// 获取指定的 pid 连接
/// </summary>
public List<ConnectionInfo> GetAllConnection(List<int> processIds)
{
var connectionInfos = _connections.Values.ToList();
var ansList = new List<ConnectionInfo>();
foreach (var t in processIds)
{
var infos = GetConnection(t);
ansList.AddRange(infos);
}
return ansList;
}
public List<ConnectionInfo> GetConnection(int processIds)
{
var connectionInfos = _connections.Values.ToList();
var infos = connectionInfos.FindAll(info => info.ProcessId == processIds);
return infos;
}
#endregion
#region 私有辅助方法