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.Repositories;
|
||||
using Shell.Utils;
|
||||
using Shell.Services;
|
||||
|
||||
namespace Shell.Controllers;
|
||||
|
||||
public class NetworkController : BaseController
|
||||
{
|
||||
private static ServerStartupManager? _serverManager;
|
||||
|
||||
public async Task GetInterfacesAsync(HttpContext context)
|
||||
{
|
||||
try
|
||||
@@ -110,7 +113,8 @@ public class NetworkController : BaseController
|
||||
var availableRanges = new List<object>();
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
availableRanges.Add(new
|
||||
@@ -218,7 +225,8 @@ public class NetworkController : BaseController
|
||||
_ => (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>
|
||||
{
|
||||
@@ -307,4 +315,93 @@ public class NetworkController : BaseController
|
||||
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);
|
||||
|
||||
// 基础API
|
||||
_server.Get("/api", async (context) =>
|
||||
{
|
||||
await context.Response.WriteJsonAsync(new { message = "Hi!" });
|
||||
});
|
||||
_server.Get("/api", async (context) => { await context.Response.WriteJsonAsync(new { message = "Hi!" }); });
|
||||
|
||||
// 订阅相关API
|
||||
RegisterSubscriptionRoutes();
|
||||
@@ -120,6 +117,7 @@ public class ApiRouteManager : IDisposable
|
||||
_server.Get("/api/realtime/active-apps", _systemController.GetActiveAppsAsync);
|
||||
_server.Get("/api/system/info", _systemController.GetSystemInfoAsync);
|
||||
_server.Get("/api/system/collection-stats", _systemController.GetCollectionStatsAsync);
|
||||
_server.Get("/api/network/realtime-stats", _networkController.GetRealTimeStatsAsync);
|
||||
}
|
||||
|
||||
private void RegisterAppAnalysisRoutes()
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Application;
|
||||
using Application.Utils;
|
||||
@@ -8,6 +11,12 @@ using Common.Net.WebSocketConn;
|
||||
using Common.Utils;
|
||||
using Utils.ETW.Etw;
|
||||
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;
|
||||
|
||||
@@ -16,6 +25,7 @@ public class ServerStartupManager
|
||||
private readonly ApiRouteManager _apiRouteManager;
|
||||
private readonly StaticFileServer _staticFileServer;
|
||||
private HighPrecisionNetworkMonitor? _networkMonitor;
|
||||
private EnhancedEtwNetworkManager? _etwNetworkManager;
|
||||
|
||||
public ServerStartupManager()
|
||||
{
|
||||
@@ -57,7 +67,15 @@ public class ServerStartupManager
|
||||
// 启动监控
|
||||
_networkMonitor.Start();
|
||||
|
||||
// 同时启动ETW监控以确保兼容性和数据完整性
|
||||
_etwNetworkManager = new EnhancedEtwNetworkManager();
|
||||
_etwNetworkManager.StartMonitoring();
|
||||
|
||||
Log.Info("高精度网络监控已启动 - 基于TCP连接表方案,解决ETW突发流量统计不准确问题");
|
||||
Log.Info("ETW网络监控已启动 - 确保数据完整性和兼容性");
|
||||
|
||||
// 设置NetworkController的ServerManager引用
|
||||
NetworkController.SetServerManager(this);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -117,6 +135,8 @@ public class ServerStartupManager
|
||||
_apiRouteManager?.Stop();
|
||||
_networkMonitor?.Stop();
|
||||
_networkMonitor?.Dispose();
|
||||
_etwNetworkManager?.StopMonitoring();
|
||||
_etwNetworkManager?.Dispose();
|
||||
}
|
||||
|
||||
#region 网络监控事件处理器
|
||||
@@ -124,25 +144,109 @@ public class ServerStartupManager
|
||||
/// <summary>
|
||||
/// 处理单个进程的网络统计更新
|
||||
/// </summary>
|
||||
private void OnProcessNetworkStatsUpdated(HighPrecisionNetworkMonitor.ProcessNetworkStats stats)
|
||||
private async void OnProcessNetworkStatsUpdated(HighPrecisionNetworkMonitor.ProcessNetworkStats stats)
|
||||
{
|
||||
// 可以在这里将统计数据推送给前端或写入数据库
|
||||
Log.Debug($"进程网络统计更新: {stats}");
|
||||
try
|
||||
{
|
||||
// 将统计数据推送给前端
|
||||
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推送给前端
|
||||
// WebSocketManager.Instance.BroadcastMessage("network_stats", stats);
|
||||
// 通过WebSocket推送给前端
|
||||
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>
|
||||
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);
|
||||
Log.Info($"系统总网速: {FormatSpeed(totalSpeed)}");
|
||||
// 计算系统总流量
|
||||
var totalUploadSpeed = statsList.Sum(s => s.BytesOutPerSecond);
|
||||
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>
|
||||
@@ -188,5 +292,68 @@ public class ServerStartupManager
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,8 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
||||
|
||||
// Class1.Main2();
|
||||
|
||||
InitWebView();
|
||||
// 延迟初始化WebView,避免构造函数中的异步调用
|
||||
this.Loaded += WebPanel_Loaded;
|
||||
|
||||
// 注册管理 WebSocket 事件
|
||||
// WebSocketManger();
|
||||
@@ -27,6 +28,18 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
||||
// 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()
|
||||
{
|
||||
if (!SysHelper.IsAdministrator())
|
||||
@@ -61,7 +74,7 @@ public partial class WebPanel : System.Windows.Controls.UserControl
|
||||
});
|
||||
}
|
||||
|
||||
private async void InitWebView()
|
||||
private async Task InitWebViewAsync()
|
||||
{
|
||||
// 初始化 WebView2
|
||||
await webView.EnsureCoreWebView2Async();
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
Width="1200"
|
||||
MinHeight="600"
|
||||
MinWidth="800"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="pack://application:,,,/Assets/Icons/app.ico">
|
||||
|
||||
<userControls:WebPanel x:Name="WebPanel" />
|
||||
WindowStartupLocation="CenterScreen">
|
||||
|
||||
<Border x:Name="WebContainer">
|
||||
</Border>
|
||||
</Window>
|
||||
@@ -3,7 +3,10 @@ using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Common.Logger;
|
||||
using Shell.UserControls;
|
||||
using Shell.Utils;
|
||||
|
||||
namespace Shell.Views;
|
||||
|
||||
@@ -11,11 +14,11 @@ public partial class TrafficAnalysisWindow : Window
|
||||
{
|
||||
private static TrafficAnalysisWindow? _instance;
|
||||
private static bool _hasRequestedElevation = false;
|
||||
|
||||
|
||||
// Win32 API for checking admin rights
|
||||
[DllImport("shell32.dll")]
|
||||
static extern bool IsUserAnAdmin();
|
||||
|
||||
|
||||
public static TrafficAnalysisWindow Instance
|
||||
{
|
||||
get
|
||||
@@ -28,7 +31,7 @@ public partial class TrafficAnalysisWindow : Window
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private TrafficAnalysisWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -37,7 +40,7 @@ public partial class TrafficAnalysisWindow : Window
|
||||
|
||||
Log.Info("TrafficAnalysisWindow 初始化");
|
||||
}
|
||||
|
||||
|
||||
public static void ShowWindow()
|
||||
{
|
||||
try
|
||||
@@ -75,7 +78,7 @@ public partial class TrafficAnalysisWindow : Window
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool IsRunningAsAdmin()
|
||||
{
|
||||
try
|
||||
@@ -90,7 +93,7 @@ public partial class TrafficAnalysisWindow : Window
|
||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void RequestElevation()
|
||||
{
|
||||
try
|
||||
@@ -116,12 +119,108 @@ public partial class TrafficAnalysisWindow : Window
|
||||
_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)
|
||||
{
|
||||
// Don't actually close, just hide the window for better performance
|
||||
@@ -129,7 +228,7 @@ public partial class TrafficAnalysisWindow : Window
|
||||
this.Hide();
|
||||
Log.Info("TrafficAnalysisWindow 隐藏");
|
||||
}
|
||||
|
||||
|
||||
// Force close method for application shutdown
|
||||
public void ForceClose()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user