如何在PowerShell中获取Win10磁盘活动时间百分比并在XAML窗体展示?
嘿,我来帮你搞定这个获取Windows 10任务管理器里的磁盘活动时间百分比,还能在XAML窗体里展示的问题!你之前搜的大多是磁盘可用/已用空间的方案,确实和这个需求不搭边,咱们一步步来解决。
先搞懂数据源:任务管理器里的“磁盘活动时间百分比”来自哪里?
其实这个数据来自Windows的性能计数器(Performance Counter),对应的是PhysicalDisk分类下的% Disk Time计数器。你之前试的Get-Counter其实是能拿到这个数据的,只是命令参数可能不对——你可以先在PowerShell里跑这个命令验证一下:
Get-Counter -Counter "\PhysicalDisk(_Total)\% Disk Time"
这个命令会返回所有磁盘的总活动时间百分比,和任务管理器里的数值是一致的。如果要监控单个磁盘,把_Total换成具体的磁盘实例名(比如0 C:),可以用Get-Counter -ListSet PhysicalDisk | Select-Object -ExpandProperty CounterInstances查看所有可用的实例名。
第二步:用C#实现监控逻辑(配合MVVM做数据绑定)
我们可以用System.Diagnostics里的PerformanceCounter类来实时读取这个数据,再通过MVVM的方式把数据绑定到XAML界面上。
首先写一个ViewModel类,负责监控和提供数据:
using System; using System.Diagnostics; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; public class DiskMonitorViewModel : INotifyPropertyChanged { private float _diskActivityPercentage; private readonly PerformanceCounter _diskCounter; private CancellationTokenSource _monitorTokenSource; // 绑定到界面的属性 public float DiskActivityPercentage { get => _diskActivityPercentage; set { _diskActivityPercentage = value; OnPropertyChanged(nameof(DiskActivityPercentage)); } } public DiskMonitorViewModel() { // 初始化性能计数器:监控所有磁盘的总活动时间 // 要监控单个磁盘的话,把InstanceName改成比如"0 C:" _diskCounter = new PerformanceCounter( categoryName: "PhysicalDisk", counterName: "% Disk Time", instanceName: "_Total", readOnly: true); } // 开始监控 public async Task StartMonitoringAsync() { _monitorTokenSource = new CancellationTokenSource(); while (!_monitorTokenSource.Token.IsCancellationRequested) { // 注意:第一次调用NextValue()会返回0,第二次才会有真实数值 var rawValue = _diskCounter.NextValue(); // 多磁盘场景下数值可能超过100%,这里做个限制,按需调整 DiskActivityPercentage = Math.Min(rawValue, 100); // 每秒刷新一次,和任务管理器频率一致 await Task.Delay(1000, _monitorTokenSource.Token); } } // 停止监控,释放资源 public void StopMonitoring() { _monitorTokenSource?.Cancel(); _diskCounter?.Dispose(); } // INotifyPropertyChanged实现,用于数据绑定更新 public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
第三步:XAML界面绑定展示
接下来写XAML窗体,把ViewModel的数据绑定到界面元素上,比如用进度条+文本显示百分比:
<Window x:Class="DiskActivityMonitor.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DiskActivityMonitor" Title="磁盘活动时间监控" Height="220" Width="350"> <!-- 设置ViewModel为窗口的数据上下文 --> <Window.DataContext> <local:DiskMonitorViewModel/> </Window.DataContext> <Grid> <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="15"> <TextBlock Text="磁盘活动时间百分比:" FontSize="18"/> <StackPanel Orientation="Horizontal" Spacing="10" VerticalAlignment="Center"> <!-- 进度条展示百分比 --> <ProgressBar Value="{Binding DiskActivityPercentage}" Width="200" Height="25" Minimum="0" Maximum="100"/> <!-- 文本显示精确百分比 --> <TextBlock Text="{Binding DiskActivityPercentage, StringFormat={}{0:F1}%}" FontSize="18" FontWeight="SemiBold"/> </StackPanel> </StackPanel> </Grid> </Window>
最后在窗口的代码后台启动监控:
using System.Windows; namespace DiskActivityMonitor { public partial class MainWindow : Window { private readonly DiskMonitorViewModel _viewModel; public MainWindow() { InitializeComponent(); _viewModel = (DiskMonitorViewModel)DataContext; } protected override async void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); // 窗口加载后开始监控 await _viewModel.StartMonitoringAsync(); } protected override void OnClosed(System.EventArgs e) { base.OnClosed(e); // 窗口关闭时停止监控,释放资源 _viewModel.StopMonitoring(); } } }
一些需要注意的点
- 权限问题:如果运行程序时出现无法读取性能计数器的错误,尝试以管理员身份启动程序,部分性能计数器需要管理员权限才能访问。
- 单个磁盘监控:如果不需要总磁盘数据,把ViewModel里的
InstanceName换成对应磁盘的实例名(比如0 C:),可以用之前提到的PowerShell命令查看所有实例。 - 第一次读取为0:性能计数器需要收集两次数据才能计算出百分比,所以程序启动后第一次显示0是正常的,第二次刷新就会有真实值。
内容的提问来源于stack exchange,提问作者Gary Allen




