A:恢复代码
This commit is contained in:
1 parent
a53ad0ab18
commit
5f3d6eda5b
6 files changed
+412
-38
No files matched your search
@@ -10,11 +10,14 @@ using Data;
|
|||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Data.Repositories;
|
using Data.Repositories;
|
||||||
using Shell.Utils;
|
using Shell.Utils;
|
||||||
|
using Shell.Services;
|
||||||
|
|
||||||
namespace Shell.Controllers;
|
namespace Shell.Controllers;
|
||||||
|
|
||||||
public class NetworkController : BaseController
|
public class NetworkController : BaseController
|
||||||
{
|
{
|
||||||
|
private static ServerStartupManager? _serverManager;
|
||||||
|
|
||||||
public async Task GetInterfacesAsync(HttpContext context)
|
public async Task GetInterfacesAsync(HttpContext context)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -110,7 +113,8 @@ public class NetworkController : BaseController
|
|||||||
var availableRanges = new List<object>();
|
var availableRanges = new List<object>();
|
||||||
var now = DateTimeOffset.UtcNow;
|
var now = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
var hasHourlyData = await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("hourly", now.AddHours(-1).ToUnixTimeSeconds());
|
var hasHourlyData =
|
||||||
|
await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("hourly", now.AddHours(-1).ToUnixTimeSeconds());
|
||||||
if (hasHourlyData)
|
if (hasHourlyData)
|
||||||
{
|
{
|
||||||
availableRanges.Add(new
|
availableRanges.Add(new
|
||||||
@@ -122,7 +126,8 @@ public class NetworkController : BaseController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasDailyData = await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-1).ToUnixTimeSeconds());
|
var hasDailyData =
|
||||||
|
await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-1).ToUnixTimeSeconds());
|
||||||
if (hasDailyData)
|
if (hasDailyData)
|
||||||
{
|
{
|
||||||
availableRanges.Add(new
|
availableRanges.Add(new
|
||||||
@@ -134,7 +139,8 @@ public class NetworkController : BaseController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasWeeklyData = await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-7).ToUnixTimeSeconds());
|
var hasWeeklyData =
|
||||||
|
await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-7).ToUnixTimeSeconds());
|
||||||
if (hasWeeklyData)
|
if (hasWeeklyData)
|
||||||
{
|
{
|
||||||
availableRanges.Add(new
|
availableRanges.Add(new
|
||||||
@@ -146,7 +152,8 @@ public class NetworkController : BaseController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasMonthlyData = await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-30).ToUnixTimeSeconds());
|
var hasMonthlyData =
|
||||||
|
await NetworkApiHelper.HasNetworkDataInTimeRangeAsync("daily", now.AddDays(-30).ToUnixTimeSeconds());
|
||||||
if (hasMonthlyData)
|
if (hasMonthlyData)
|
||||||
{
|
{
|
||||||
availableRanges.Add(new
|
availableRanges.Add(new
|
||||||
@@ -218,7 +225,8 @@ public class NetworkController : BaseController
|
|||||||
_ => (now.AddHours(-1).ToUnixTimeSeconds(), "hour")
|
_ => (now.AddHours(-1).ToUnixTimeSeconds(), "hour")
|
||||||
};
|
};
|
||||||
|
|
||||||
var points = await NetworkApiHelper.GetTrafficTrendsAsync(mappedTimeRange, interfaceId, startTime, now.ToUnixTimeSeconds());
|
var points = await NetworkApiHelper.GetTrafficTrendsAsync(mappedTimeRange, interfaceId, startTime,
|
||||||
|
now.ToUnixTimeSeconds());
|
||||||
|
|
||||||
await WriteJsonResponseAsync(context, new ResponseModel<object>
|
await WriteJsonResponseAsync(context, new ResponseModel<object>
|
||||||
{
|
{
|
||||||
@@ -307,4 +315,93 @@ public class NetworkController : BaseController
|
|||||||
await WriteErrorResponseAsync(context, $"获取Top应用流量数据失败: {ex.Message}", 500);
|
await WriteErrorResponseAsync(context, $"获取Top应用流量数据失败: {ex.Message}", 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取实时网络统计数据
|
||||||
|
/// </summary>
|
||||||
|
public async Task GetRealTimeStatsAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_serverManager == null)
|
||||||
|
{
|
||||||
|
await WriteErrorResponseAsync(context, "网络监控服务未启动", 503);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有活跃进程的实时统计
|
||||||
|
var activeProcessStats = _serverManager.GetAllActiveProcessStats();
|
||||||
|
|
||||||
|
// 计算总体统计
|
||||||
|
var totalUploadSpeed = activeProcessStats.Sum(s => s.BytesOutPerSecond);
|
||||||
|
var totalDownloadSpeed = activeProcessStats.Sum(s => s.BytesInPerSecond);
|
||||||
|
var totalSpeed = totalUploadSpeed + totalDownloadSpeed;
|
||||||
|
|
||||||
|
// 格式化进程列表
|
||||||
|
var processes = activeProcessStats.OrderByDescending(s => s.TotalBytesPerSecond)
|
||||||
|
.Take(20) // 只返回前20个活跃进程
|
||||||
|
.Select(s => new
|
||||||
|
{
|
||||||
|
processId = s.ProcessId,
|
||||||
|
processName = s.ProcessName,
|
||||||
|
connectionCount = s.ConnectionCount,
|
||||||
|
bytesInPerSecond = s.BytesInPerSecond,
|
||||||
|
bytesOutPerSecond = s.BytesOutPerSecond,
|
||||||
|
totalBytesPerSecond = s.TotalBytesPerSecond,
|
||||||
|
formattedDownloadSpeed = s.FormattedDownloadSpeed,
|
||||||
|
formattedUploadSpeed = s.FormattedUploadSpeed,
|
||||||
|
formattedTotalSpeed = s.FormattedTotalSpeed,
|
||||||
|
lastUpdate = s.LastUpdate
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
timestamp = DateTime.Now,
|
||||||
|
summary = new
|
||||||
|
{
|
||||||
|
totalUploadSpeed = totalUploadSpeed,
|
||||||
|
totalDownloadSpeed = totalDownloadSpeed,
|
||||||
|
totalSpeed = totalSpeed,
|
||||||
|
formattedUploadSpeed = FormatSpeed(totalUploadSpeed),
|
||||||
|
formattedDownloadSpeed = FormatSpeed(totalDownloadSpeed),
|
||||||
|
formattedTotalSpeed = FormatSpeed(totalSpeed),
|
||||||
|
activeProcessCount = activeProcessStats.Count
|
||||||
|
},
|
||||||
|
processes = processes
|
||||||
|
};
|
||||||
|
|
||||||
|
await WriteJsonResponseAsync(context, new ResponseModel<object>
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Data = result,
|
||||||
|
Message = "获取实时网络统计成功"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await WriteErrorResponseAsync(context, $"获取实时网络统计失败: {ex.Message}", 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置ServerStartupManager实例(供启动时调用)
|
||||||
|
/// </summary>
|
||||||
|
public static void SetServerManager(ServerStartupManager serverManager)
|
||||||
|
{
|
||||||
|
_serverManager = serverManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 格式化网速显示
|
||||||
|
/// </summary>
|
||||||
|
private static string FormatSpeed(double bytesPerSec)
|
||||||
|
{
|
||||||
|
if (bytesPerSec >= 1024 * 1024 * 1024)
|
||||||
|
return $"{bytesPerSec / (1024.0 * 1024 * 1024):F1} GB/s";
|
||||||
|
if (bytesPerSec >= 1024 * 1024)
|
||||||
|
return $"{bytesPerSec / (1024.0 * 1024):F1} MB/s";
|
||||||
|
if (bytesPerSec >= 1024)
|
||||||
|
return $"{bytesPerSec / 1024.0:F1} KB/s";
|
||||||
|
return $"{bytesPerSec:F0} B/s";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,10 +34,7 @@ public class ApiRouteManager : IDisposable
|
|||||||
_server.UseMiddleware(Middlewares.Cors);
|
_server.UseMiddleware(Middlewares.Cors);
|
||||||
|
|
||||||
// 基础API
|
// 基础API
|
||||||
_server.Get("/api", async (context) =>
|
_server.Get("/api", async (context) => { await context.Response.WriteJsonAsync(new { message = "Hi!" }); });
|
||||||
{
|
|
||||||
await context.Response.WriteJsonAsync(new { message = "Hi!" });
|
|
||||||
});
|
|
||||||
|
|
||||||
// 订阅相关API
|
// 订阅相关API
|
||||||
RegisterSubscriptionRoutes();
|
RegisterSubscriptionRoutes();
|
||||||
@@ -120,6 +117,7 @@ public class ApiRouteManager : IDisposable
|
|||||||
_server.Get("/api/realtime/active-apps", _systemController.GetActiveAppsAsync);
|
_server.Get("/api/realtime/active-apps", _systemController.GetActiveAppsAsync);
|
||||||
_server.Get("/api/system/info", _systemController.GetSystemInfoAsync);
|
_server.Get("/api/system/info", _systemController.GetSystemInfoAsync);
|
||||||
_server.Get("/api/system/collection-stats", _systemController.GetCollectionStatsAsync);
|
_server.Get("/api/system/collection-stats", _systemController.GetCollectionStatsAsync);
|
||||||
|
_server.Get("/api/network/realtime-stats", _networkController.GetRealTimeStatsAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterAppAnalysisRoutes()
|
private void RegisterAppAnalysisRoutes()
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Application;
|
using Application;
|
||||||
using Application.Utils;
|
using Application.Utils;
|
||||||
@@ -8,6 +11,12 @@ using Common.Net.WebSocketConn;
|
|||||||
using Common.Utils;
|
using Common.Utils;
|
||||||
using Utils.ETW.Etw;
|
using Utils.ETW.Etw;
|
||||||
using Utils.ETW.Core;
|
using Utils.ETW.Core;
|
||||||
|
using Utils.ETW.Models;
|
||||||
|
using Infrastructure.Models;
|
||||||
|
using Infrastructure.utils;
|
||||||
|
using Data;
|
||||||
|
using Data.Models;
|
||||||
|
using Shell.Controllers;
|
||||||
|
|
||||||
namespace Shell.Services;
|
namespace Shell.Services;
|
||||||
|
|
||||||
@@ -16,6 +25,7 @@ public class ServerStartupManager
|
|||||||
private readonly ApiRouteManager _apiRouteManager;
|
private readonly ApiRouteManager _apiRouteManager;
|
||||||
private readonly StaticFileServer _staticFileServer;
|
private readonly StaticFileServer _staticFileServer;
|
||||||
private HighPrecisionNetworkMonitor? _networkMonitor;
|
private HighPrecisionNetworkMonitor? _networkMonitor;
|
||||||
|
private EnhancedEtwNetworkManager? _etwNetworkManager;
|
||||||
|
|
||||||
public ServerStartupManager()
|
public ServerStartupManager()
|
||||||
{
|
{
|
||||||
@@ -57,7 +67,15 @@ public class ServerStartupManager
|
|||||||
// 启动监控
|
// 启动监控
|
||||||
_networkMonitor.Start();
|
_networkMonitor.Start();
|
||||||
|
|
||||||
|
// 同时启动ETW监控以确保兼容性和数据完整性
|
||||||
|
_etwNetworkManager = new EnhancedEtwNetworkManager();
|
||||||
|
_etwNetworkManager.StartMonitoring();
|
||||||
|
|
||||||
Log.Info("高精度网络监控已启动 - 基于TCP连接表方案,解决ETW突发流量统计不准确问题");
|
Log.Info("高精度网络监控已启动 - 基于TCP连接表方案,解决ETW突发流量统计不准确问题");
|
||||||
|
Log.Info("ETW网络监控已启动 - 确保数据完整性和兼容性");
|
||||||
|
|
||||||
|
// 设置NetworkController的ServerManager引用
|
||||||
|
NetworkController.SetServerManager(this);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -117,6 +135,8 @@ public class ServerStartupManager
|
|||||||
_apiRouteManager?.Stop();
|
_apiRouteManager?.Stop();
|
||||||
_networkMonitor?.Stop();
|
_networkMonitor?.Stop();
|
||||||
_networkMonitor?.Dispose();
|
_networkMonitor?.Dispose();
|
||||||
|
_etwNetworkManager?.StopMonitoring();
|
||||||
|
_etwNetworkManager?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 网络监控事件处理器
|
#region 网络监控事件处理器
|
||||||
@@ -124,25 +144,109 @@ public class ServerStartupManager
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理单个进程的网络统计更新
|
/// 处理单个进程的网络统计更新
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnProcessNetworkStatsUpdated(HighPrecisionNetworkMonitor.ProcessNetworkStats stats)
|
private async void OnProcessNetworkStatsUpdated(HighPrecisionNetworkMonitor.ProcessNetworkStats stats)
|
||||||
{
|
{
|
||||||
// 可以在这里将统计数据推送给前端或写入数据库
|
try
|
||||||
Log.Debug($"进程网络统计更新: {stats}");
|
{
|
||||||
|
// 将统计数据推送给前端
|
||||||
|
var networkData = new
|
||||||
|
{
|
||||||
|
type = "process_network_stats",
|
||||||
|
data = new
|
||||||
|
{
|
||||||
|
processId = stats.ProcessId,
|
||||||
|
processName = stats.ProcessName,
|
||||||
|
connectionCount = stats.ConnectionCount,
|
||||||
|
bytesInPerSecond = stats.BytesInPerSecond,
|
||||||
|
bytesOutPerSecond = stats.BytesOutPerSecond,
|
||||||
|
totalBytesPerSecond = stats.TotalBytesPerSecond,
|
||||||
|
formattedDownloadSpeed = stats.FormattedDownloadSpeed,
|
||||||
|
formattedUploadSpeed = stats.FormattedUploadSpeed,
|
||||||
|
formattedTotalSpeed = stats.FormattedTotalSpeed,
|
||||||
|
lastUpdate = stats.LastUpdate
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 示例:通过WebSocket推送给前端
|
// 通过WebSocket推送给前端
|
||||||
// WebSocketManager.Instance.BroadcastMessage("network_stats", stats);
|
var message = new Common.Net.WebSocketConn.ResponseMessage
|
||||||
|
{
|
||||||
|
Type = "network_stats",
|
||||||
|
Data = networkData,
|
||||||
|
Success = true
|
||||||
|
};
|
||||||
|
await WebSocketManager.Instance.BroadcastMessage(message);
|
||||||
|
|
||||||
|
// 更新到GlobalNetworkMonitor以保持兼容性
|
||||||
|
UpdateGlobalNetworkMonitorWithStats(stats);
|
||||||
|
|
||||||
|
Log.Debug($"进程网络统计更新: {stats}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"处理进程网络统计更新时出错: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理所有活跃进程的网络统计批量更新
|
/// 处理所有活跃进程的网络统计批量更新
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnAllProcessStatsUpdated(List<HighPrecisionNetworkMonitor.ProcessNetworkStats> statsList)
|
private async void OnAllProcessStatsUpdated(List<HighPrecisionNetworkMonitor.ProcessNetworkStats> statsList)
|
||||||
{
|
{
|
||||||
Log.Debug($"批量网络统计更新: {statsList.Count} 个活跃进程");
|
try
|
||||||
|
{
|
||||||
|
Log.Debug($"批量网络统计更新: {statsList.Count} 个活跃进程");
|
||||||
|
|
||||||
// 示例:可以在这里进行数据聚合或向前端推送汇总信息
|
// 计算系统总流量
|
||||||
var totalSpeed = statsList.Sum(s => s.TotalBytesPerSecond);
|
var totalUploadSpeed = statsList.Sum(s => s.BytesOutPerSecond);
|
||||||
Log.Info($"系统总网速: {FormatSpeed(totalSpeed)}");
|
var totalDownloadSpeed = statsList.Sum(s => s.BytesInPerSecond);
|
||||||
|
var totalSpeed = totalUploadSpeed + totalDownloadSpeed;
|
||||||
|
|
||||||
|
// 创建全局网络统计数据
|
||||||
|
var globalStats = new
|
||||||
|
{
|
||||||
|
type = "global_network_stats",
|
||||||
|
data = new
|
||||||
|
{
|
||||||
|
activeProcessCount = statsList.Count,
|
||||||
|
totalUploadSpeed = totalUploadSpeed,
|
||||||
|
totalDownloadSpeed = totalDownloadSpeed,
|
||||||
|
totalSpeed = totalSpeed,
|
||||||
|
formattedUploadSpeed = FormatSpeed(totalUploadSpeed),
|
||||||
|
formattedDownloadSpeed = FormatSpeed(totalDownloadSpeed),
|
||||||
|
formattedTotalSpeed = FormatSpeed(totalSpeed),
|
||||||
|
timestamp = DateTime.Now,
|
||||||
|
topProcesses = statsList.OrderByDescending(s => s.TotalBytesPerSecond)
|
||||||
|
.Take(5)
|
||||||
|
.Select(s => new
|
||||||
|
{
|
||||||
|
processId = s.ProcessId,
|
||||||
|
processName = s.ProcessName,
|
||||||
|
speed = s.TotalBytesPerSecond,
|
||||||
|
formattedSpeed = s.FormattedTotalSpeed
|
||||||
|
})
|
||||||
|
.ToList()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 推送全局统计给前端
|
||||||
|
var globalMessage = new Common.Net.WebSocketConn.ResponseMessage
|
||||||
|
{
|
||||||
|
Type = "global_network_stats",
|
||||||
|
Data = globalStats,
|
||||||
|
Success = true
|
||||||
|
};
|
||||||
|
await WebSocketManager.Instance.BroadcastMessage(globalMessage);
|
||||||
|
|
||||||
|
// 存储全局网络数据到数据库
|
||||||
|
_ = Task.Run(() => SaveGlobalNetworkStatsAsync(totalUploadSpeed, totalDownloadSpeed));
|
||||||
|
|
||||||
|
Log.Info(
|
||||||
|
$"系统总网速: {FormatSpeed(totalSpeed)} (↑{FormatSpeed(totalUploadSpeed)} ↓{FormatSpeed(totalDownloadSpeed)})");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"处理批量网络统计更新时出错: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -188,5 +292,68 @@ public class ServerStartupManager
|
|||||||
new List<HighPrecisionNetworkMonitor.ProcessNetworkStats>();
|
new List<HighPrecisionNetworkMonitor.ProcessNetworkStats>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新GlobalNetworkMonitor以保持兼容性
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateGlobalNetworkMonitorWithStats(HighPrecisionNetworkMonitor.ProcessNetworkStats stats)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 创建一个NetworkModel来更新GlobalNetworkMonitor
|
||||||
|
var networkModel = new NetworkModel
|
||||||
|
{
|
||||||
|
ProcessId = (int)stats.ProcessId,
|
||||||
|
ThreadId = 0, // 使用默认值
|
||||||
|
ProcessName = stats.ProcessName,
|
||||||
|
SourceIp = IPAddress.Loopback, // 使用默认值
|
||||||
|
DestinationIp = IPAddress.Loopback, // 使用默认值
|
||||||
|
SourcePort = 0, // 使用默认值
|
||||||
|
DestinationPort = 0, // 使用默认值
|
||||||
|
ConnectType = ProtocolType.TCP, // 使用TCP
|
||||||
|
IsPartialConnection = false, // 使用默认值
|
||||||
|
BytesSent = (long)stats.BytesOutPerSecond, // 当前秒的发送字节数
|
||||||
|
BytesReceived = (long)stats.BytesInPerSecond, // 当前秒的接收字节数
|
||||||
|
LastSeenTime = DateTime.Now,
|
||||||
|
RecordTime = stats.LastUpdate,
|
||||||
|
IsIncrementalData = true,
|
||||||
|
State = ConnectionState.Connected
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新到GlobalNetworkMonitor
|
||||||
|
GlobalNetworkMonitor.Instance.UpdateConnectionInfo(networkModel);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"更新GlobalNetworkMonitor时出错: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步保存全局网络统计到数据库
|
||||||
|
/// </summary>
|
||||||
|
private async Task SaveGlobalNetworkStatsAsync(double uploadSpeed, double downloadSpeed)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
|
|
||||||
|
// 创建全局网络记录
|
||||||
|
var globalNetwork = new GlobalNetwork
|
||||||
|
{
|
||||||
|
Timestep = timestamp,
|
||||||
|
Upload = (long)uploadSpeed,
|
||||||
|
Download = (long)downloadSpeed,
|
||||||
|
NetworkCardGuid = "system_total" // 使用固定值表示系统总计
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
await DatabaseManager.Instance.Networks.SaveGlobalNetworkAsync(globalNetwork);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"保存全局网络统计到数据库时出错: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,8 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
|||||||
|
|
||||||
// Class1.Main2();
|
// Class1.Main2();
|
||||||
|
|
||||||
InitWebView();
|
// 延迟初始化WebView,避免构造函数中的异步调用
|
||||||
|
this.Loaded += WebPanel_Loaded;
|
||||||
|
|
||||||
// 注册管理 WebSocket 事件
|
// 注册管理 WebSocket 事件
|
||||||
// WebSocketManger();
|
// WebSocketManger();
|
||||||
@@ -27,6 +28,18 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
|||||||
// NewMethod();
|
// NewMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void WebPanel_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await InitWebViewAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"WebView初始化失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task NewMethod()
|
private static async Task NewMethod()
|
||||||
{
|
{
|
||||||
if (!SysHelper.IsAdministrator())
|
if (!SysHelper.IsAdministrator())
|
||||||
@@ -61,7 +74,7 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void InitWebView()
|
private async Task InitWebViewAsync()
|
||||||
{
|
{
|
||||||
// 初始化 WebView2
|
// 初始化 WebView2
|
||||||
await webView.EnsureCoreWebView2Async();
|
await webView.EnsureCoreWebView2Async();
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
Width="1200"
|
Width="1200"
|
||||||
MinHeight="600"
|
MinHeight="600"
|
||||||
MinWidth="800"
|
MinWidth="800"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen">
|
||||||
Icon="pack://application:,,,/Assets/Icons/app.ico">
|
|
||||||
|
<Border x:Name="WebContainer">
|
||||||
<userControls:WebPanel x:Name="WebPanel" />
|
</Border>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -3,7 +3,10 @@ using System.Diagnostics;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using Common.Logger;
|
using Common.Logger;
|
||||||
|
using Shell.UserControls;
|
||||||
|
using Shell.Utils;
|
||||||
|
|
||||||
namespace Shell.Views;
|
namespace Shell.Views;
|
||||||
|
|
||||||
@@ -11,11 +14,11 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
{
|
{
|
||||||
private static TrafficAnalysisWindow? _instance;
|
private static TrafficAnalysisWindow? _instance;
|
||||||
private static bool _hasRequestedElevation = false;
|
private static bool _hasRequestedElevation = false;
|
||||||
|
|
||||||
// Win32 API for checking admin rights
|
// Win32 API for checking admin rights
|
||||||
[DllImport("shell32.dll")]
|
[DllImport("shell32.dll")]
|
||||||
static extern bool IsUserAnAdmin();
|
static extern bool IsUserAnAdmin();
|
||||||
|
|
||||||
public static TrafficAnalysisWindow Instance
|
public static TrafficAnalysisWindow Instance
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -28,7 +31,7 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TrafficAnalysisWindow()
|
private TrafficAnalysisWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -37,7 +40,7 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
|
|
||||||
Log.Info("TrafficAnalysisWindow 初始化");
|
Log.Info("TrafficAnalysisWindow 初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowWindow()
|
public static void ShowWindow()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -75,7 +78,7 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsRunningAsAdmin()
|
private static bool IsRunningAsAdmin()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -90,7 +93,7 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RequestElevation()
|
private static void RequestElevation()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -116,12 +119,108 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
_hasRequestedElevation = true; // Don't ask again in this session
|
_hasRequestedElevation = true; // Don't ask again in this session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TrafficAnalysisWindow_Loaded(object sender, RoutedEventArgs e)
|
private async void TrafficAnalysisWindow_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Log.Info("TrafficAnalysisWindow 加载完成");
|
try
|
||||||
|
{
|
||||||
|
Log.Info("TrafficAnalysisWindow 加载完成");
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
|
||||||
|
// 检查WebView2是否可用
|
||||||
|
bool hasWebView2 = await WebView2Helper.IsWebView2RuntimeInstalled();
|
||||||
|
|
||||||
|
if (hasWebView2)
|
||||||
|
{
|
||||||
|
// 创建WebPanel并添加到容器
|
||||||
|
var webPanel = new WebPanel();
|
||||||
|
WebContainer.Child = webPanel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 显示简化的错误界面
|
||||||
|
var errorPanel = CreateErrorPanel();
|
||||||
|
WebContainer.Child = errorPanel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"TrafficAnalysisWindow加载时发生错误: {ex.Message}");
|
||||||
|
|
||||||
|
// 显示错误界面
|
||||||
|
var errorPanel = CreateErrorPanel(ex.Message);
|
||||||
|
WebContainer.Child = errorPanel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StackPanel CreateErrorPanel(string errorMessage = null)
|
||||||
|
{
|
||||||
|
var panel = new StackPanel
|
||||||
|
{
|
||||||
|
Margin = new Thickness(20),
|
||||||
|
VerticalAlignment = System.Windows.VerticalAlignment.Center,
|
||||||
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Center
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = "⚠️ 流量分析功能不可用",
|
||||||
|
FontSize = 18,
|
||||||
|
FontWeight = FontWeights.Bold,
|
||||||
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
|
||||||
|
Margin = new Thickness(0, 0, 0, 20)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(errorMessage))
|
||||||
|
{
|
||||||
|
panel.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = "需要安装 Microsoft Edge WebView2 运行时才能使用此功能。",
|
||||||
|
FontSize = 14,
|
||||||
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
|
||||||
|
Margin = new Thickness(0, 0, 0, 10),
|
||||||
|
TextWrapping = TextWrapping.Wrap
|
||||||
|
});
|
||||||
|
|
||||||
|
var downloadButton = new System.Windows.Controls.Button
|
||||||
|
{
|
||||||
|
Content = "下载 WebView2 运行时",
|
||||||
|
Padding = new Thickness(15, 8, 15, 8),
|
||||||
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Center
|
||||||
|
};
|
||||||
|
downloadButton.Click += (s, e) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "https://go.microsoft.com/fwlink/p/?LinkId=2124703",
|
||||||
|
UseShellExecute = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"无法打开下载链接: {ex.Message}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
panel.Children.Add(downloadButton);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panel.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = $"错误信息: {errorMessage}",
|
||||||
|
FontSize = 12,
|
||||||
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
|
||||||
|
Foreground = System.Windows.Media.Brushes.Red,
|
||||||
|
TextWrapping = TextWrapping.Wrap
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
private void TrafficAnalysisWindow_Closing(object sender, CancelEventArgs e)
|
private void TrafficAnalysisWindow_Closing(object sender, CancelEventArgs e)
|
||||||
{
|
{
|
||||||
// Don't actually close, just hide the window for better performance
|
// Don't actually close, just hide the window for better performance
|
||||||
@@ -129,7 +228,7 @@ public partial class TrafficAnalysisWindow : Window
|
|||||||
this.Hide();
|
this.Hide();
|
||||||
Log.Info("TrafficAnalysisWindow 隐藏");
|
Log.Info("TrafficAnalysisWindow 隐藏");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force close method for application shutdown
|
// Force close method for application shutdown
|
||||||
public void ForceClose()
|
public void ForceClose()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user