You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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

火山引擎 最新活动