最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C# WinForms開發(fā)的Windows系統(tǒng)監(jiān)控工具

 更新時間:2025年12月25日 08:58:27   作者:應用市場  
最近開發(fā)了一個輕量級的 Windows 系統(tǒng)監(jiān)控工具,可以實時監(jiān)控 CPU、內(nèi)存、GPU、溫度、網(wǎng)絡(luò)流量等硬件信息,并通過曲線圖表直觀展示,本文分享一下開發(fā)過程中的核心技術(shù)點和關(guān)鍵代碼實現(xiàn),需要的朋友可以參考下

前言

最近開發(fā)了一個輕量級的 Windows 系統(tǒng)監(jiān)控工具,可以實時監(jiān)控 CPU、內(nèi)存、GPU、溫度、網(wǎng)絡(luò)流量等硬件信息,并通過曲線圖表直觀展示。整個項目基于 .NET 10.0 和 WinForms 框架,使用了 LibreHardwareMonitor 硬件監(jiān)控庫和 ScottPlot 圖表庫。

本文分享一下開發(fā)過程中的核心技術(shù)點和關(guān)鍵代碼實現(xiàn)。

技術(shù)棧

  • .NET 10.0 - 最新的 .NET 平臺
  • Windows Forms - 桌面 UI 框架
  • LibreHardwareMonitor 0.9.3 - 硬件傳感器數(shù)據(jù)采集
  • ScottPlot 5.0 - 高性能實時圖表繪制
  • PerformanceCounter - Windows 性能計數(shù)器

核心功能

  1. 實時監(jiān)控 CPU 使用率、主頻、溫度
  2. 內(nèi)存使用情況監(jiān)控
  3. GPU 使用率和溫度監(jiān)控
  4. 網(wǎng)絡(luò)上傳/下載速度統(tǒng)計
  5. 磁盤 I/O 讀寫速度
  6. 電池電量和充電狀態(tài)(筆記本)
  7. 歷史數(shù)據(jù)曲線圖表展示
  8. 任務欄懸浮小窗口(支持三種顯示模式)
  9. 配置持久化存儲

一、硬件監(jiān)控實現(xiàn)

1.1 系統(tǒng)監(jiān)控服務設(shè)計

系統(tǒng)監(jiān)控服務是整個工具的核心,負責采集各類硬件數(shù)據(jù)。主要使用兩種方式:

  • PerformanceCounter:采集 CPU 使用率、內(nèi)存使用率、網(wǎng)絡(luò)流量等
  • LibreHardwareMonitor:采集溫度、頻率、GPU 等硬件傳感器數(shù)據(jù)

核心數(shù)據(jù)結(jié)構(gòu):

public class MonitorData
{
    // CPU信息
    public float CpuUsage { get; set; }
    public float CpuFrequency { get; set; }  // CPU當前主頻 (MHz)
    public float CpuTemperature { get; set; }
    public int CpuCoreCount { get; set; }
    public int CpuThreadCount { get; set; }
    public string CpuName { get; set; } = string.Empty;

    // 內(nèi)存信息
    public float MemoryUsage { get; set; }
    public long TotalMemoryMB { get; set; }
    public long UsedMemoryMB { get; set; }
    public long AvailableMemoryMB { get; set; }

    // GPU信息
    public float GpuTemperature { get; set; }
    public float GpuUsage { get; set; }
    public string GpuName { get; set; } = string.Empty;

    // 網(wǎng)絡(luò)信息
    public float NetworkUploadSpeed { get; set; }    // KB/s
    public float NetworkDownloadSpeed { get; set; }  // KB/s

    // 磁盤信息
    public float DiskUsage { get; set; }
    public long DiskReadSpeed { get; set; }
    public long DiskWriteSpeed { get; set; }

    // 電池信息
    public int BatteryLevel { get; set; }
    public bool IsCharging { get; set; }
}

1.2 性能計數(shù)器初始化

public class SystemMonitor : IDisposable
{
    private readonly Computer _computer;
    private readonly PerformanceCounter _cpuCounter;
    private readonly PerformanceCounter _ramCounter;
    private PerformanceCounter? _networkSentCounter;
    private PerformanceCounter? _networkReceivedCounter;

    public SystemMonitor()
    {
        // 初始化性能計數(shù)器
        _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        _ramCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use");

        // 初始化網(wǎng)絡(luò)計數(shù)器
        InitializeNetworkCounters();

        // 初始化 LibreHardwareMonitor
        _computer = new Computer
        {
            IsCpuEnabled = true,
            IsGpuEnabled = true,
            IsMemoryEnabled = true,
            IsBatteryEnabled = true,
            IsNetworkEnabled = true,
            IsStorageEnabled = true
        };
        _computer.Open();
    }
}

1.3 網(wǎng)絡(luò)流量監(jiān)控

網(wǎng)絡(luò)流量監(jiān)控需要注意的是 PerformanceCounter 返回的是累計值,需要計算兩次采樣之間的差值來得到速度:

private void InitializeNetworkCounters()
{
    try
    {
        var category = new PerformanceCounterCategory("Network Interface");
        var instanceNames = category.GetInstanceNames();
        if (instanceNames.Length > 0)
        {
            string networkInterface = instanceNames[0];
            _networkSentCounter = new PerformanceCounter(
                "Network Interface", "Bytes Sent/sec", networkInterface);
            _networkReceivedCounter = new PerformanceCounter(
                "Network Interface", "Bytes Received/sec", networkInterface);
        }
    }
    catch { }
}

private void UpdateNetworkData(MonitorData data)
{
    try
    {
        if (_networkSentCounter != null && _networkReceivedCounter != null)
        {
            long bytesSent = (long)_networkSentCounter.NextValue();
            long bytesReceived = (long)_networkReceivedCounter.NextValue();

            var now = DateTime.Now;
            var timeDiff = (now - _lastNetworkUpdate).TotalSeconds;

            if (timeDiff > 0 && _lastBytesSent > 0)
            {
                // 計算速度 (KB/s)
                data.NetworkUploadSpeed =
                    (float)((bytesSent - _lastBytesSent) / timeDiff / 1024);
                data.NetworkDownloadSpeed =
                    (float)((bytesReceived - _lastBytesReceived) / timeDiff / 1024);
            }

            _lastBytesSent = bytesSent;
            _lastBytesReceived = bytesReceived;
            _lastNetworkUpdate = now;
        }
    }
    catch { }
}

1.4 溫度和頻率監(jiān)控

使用 LibreHardwareMonitor 獲取 CPU/GPU 溫度和頻率信息:

private void UpdateData()
{
    var data = new MonitorData();

    // 獲取 CPU 使用率
    data.CpuUsage = _cpuCounter.NextValue();

    // 更新硬件傳感器信息
    foreach (var hardware in _computer.Hardware)
    {
        hardware.Update();

        // CPU 溫度和頻率
        if (hardware.HardwareType == HardwareType.Cpu)
        {
            foreach (var sensor in hardware.Sensors)
            {
                if (sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue)
                {
                    data.CpuTemperature = Math.Max(data.CpuTemperature, sensor.Value.Value);
                }

                // 獲取 CPU 主頻
                if (sensor.SensorType == SensorType.Clock &&
                    sensor.Name.Contains("Core") && sensor.Value.HasValue)
                {
                    data.CpuFrequency = Math.Max(data.CpuFrequency, sensor.Value.Value);
                }
            }
        }

        // GPU 溫度和使用率
        if (hardware.HardwareType == HardwareType.GpuNvidia ||
            hardware.HardwareType == HardwareType.GpuAmd ||
            hardware.HardwareType == HardwareType.GpuIntel)
        {
            foreach (var sensor in hardware.Sensors)
            {
                if (sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue)
                {
                    data.GpuTemperature = Math.Max(data.GpuTemperature, sensor.Value.Value);
                }

                if (sensor.SensorType == SensorType.Load &&
                    sensor.Name.Contains("Core") && sensor.Value.HasValue)
                {
                    data.GpuUsage = Math.Max(data.GpuUsage, sensor.Value.Value);
                }
            }
        }
    }

    DataUpdated?.Invoke(this, data);
}

1.5 電池狀態(tài)監(jiān)控(Win11 兼容)

電池狀態(tài)監(jiān)控在 Win11 上需要特別處理,使用 SystemInformation.PowerStatus API:

try
{
    var status = System.Windows.Forms.SystemInformation.PowerStatus;

    // 檢查是否有電池
    if (status.BatteryLifePercent >= 0 && status.BatteryLifePercent <= 1 &&
        status.BatteryChargeStatus != System.Windows.Forms.BatteryChargeStatus.NoSystemBattery)
    {
        // 電池百分比
        data.BatteryLevel = (int)(status.BatteryLifePercent * 100);

        // 充電狀態(tài)
        data.IsCharging = status.PowerLineStatus == System.Windows.Forms.PowerLineStatus.Online ||
                         status.BatteryChargeStatus.HasFlag(System.Windows.Forms.BatteryChargeStatus.Charging);
    }
    else
    {
        // 臺式機或沒有電池的設(shè)備
        data.BatteryLevel = -1;  // 用 -1 表示無電池
        data.IsCharging = false;
    }
}
catch
{
    data.BatteryLevel = -1;
    data.IsCharging = false;
}

二、歷史數(shù)據(jù)管理

為了繪制歷史曲線,需要維護一個固定大小的數(shù)據(jù)隊列:

public class DataHistory
{
    private readonly int _maxDataPoints;
    private readonly Queue<float> _cpuHistory;
    private readonly Queue<float> _memoryHistory;
    private readonly Queue<float> _cpuTempHistory;
    private readonly Queue<float> _gpuTempHistory;
    // ... 其他數(shù)據(jù)隊列

    public DataHistory(int maxDataPoints = 60)
    {
        _maxDataPoints = maxDataPoints;
        _cpuHistory = new Queue<float>(maxDataPoints);
        _memoryHistory = new Queue<float>(maxDataPoints);
        // 初始化其他隊列...
    }

    public void AddData(MonitorData data)
    {
        AddToQueue(_cpuHistory, data.CpuUsage);
        AddToQueue(_memoryHistory, data.MemoryUsage);
        AddToQueue(_cpuTempHistory, data.CpuTemperature);
        // 添加其他數(shù)據(jù)...
    }

    private void AddToQueue(Queue<float> queue, float value)
    {
        if (queue.Count >= _maxDataPoints)
        {
            queue.Dequeue();
        }
        queue.Enqueue(value);
    }

    public double[] GetCpuHistory() => _cpuHistory.Select(x => (double)x).ToArray();
    public double[] GetMemoryHistory() => _memoryHistory.Select(x => (double)x).ToArray();
    // 其他獲取方法...
}

三、ScottPlot 圖表繪制

3.1 圖表初始化

ScottPlot 5.0 提供了強大的實時圖表繪制能力:

private void SetupPlot(FormsPlot plot, string title, Color lineColor, double yMin = 0, double yMax = 100)
{
    plot.Plot.Title(title);
    plot.Plot.Axes.Title.Label.ForeColor = ScottColor.FromColor(Color.White);
    plot.Plot.FigureBackground.Color = ScottColor.FromColor(Color.FromArgb(40, 40, 40));
    plot.Plot.DataBackground.Color = ScottColor.FromColor(Color.FromArgb(30, 30, 30));
    plot.Plot.Axes.Color(ScottColor.FromColor(Color.Gray));
    plot.Plot.Grid.MajorLineColor = ScottColor.FromColor(Color.FromArgb(60, 60, 60));

    // 設(shè)置 Y 軸范圍
    plot.Plot.Axes.SetLimitsY(yMin, yMax);
}

3.2 單線圖表更新

private void UpdatePlot(FormsPlot? plot, double[] data, Color lineColor)
{
    if (plot == null || data.Length == 0) return;

    plot.Plot.Clear();

    var signal = plot.Plot.Add.Signal(data);
    signal.Color = ScottColor.FromColor(lineColor);
    signal.LineWidth = 2;

    plot.Plot.Axes.SetLimitsX(0, data.Length);
    plot.Plot.Axes.SetLimitsY(0, 100);

    plot.Refresh();
}

3.3 雙線圖表(溫度/網(wǎng)絡(luò))

溫度圖表同時顯示 CPU 和 GPU 溫度,網(wǎng)絡(luò)圖表同時顯示上傳和下載速度:

private void UpdateDualLinePlot(FormsPlot? plot, double[] data1, double[] data2,
    string legend1, string legend2, Color color1, Color color2)
{
    if (plot == null) return;

    plot.Plot.Clear();

    if (data1.Length > 0)
    {
        var signal1 = plot.Plot.Add.Signal(data1);
        signal1.Color = ScottColor.FromColor(color1);
        signal1.LineWidth = 2;
        signal1.LegendText = legend1;
    }

    if (data2.Length > 0)
    {
        var signal2 = plot.Plot.Add.Signal(data2);
        signal2.Color = ScottColor.FromColor(color2);
        signal2.LineWidth = 2;
        signal2.LegendText = legend2;
    }

    plot.Plot.ShowLegend();
    plot.Plot.Axes.SetLimitsX(0, Math.Max(data1.Length, data2.Length));

    // 自動調(diào)整 Y 軸范圍
    if (data1.Length > 0 || data2.Length > 0)
    {
        double maxValue = 0;
        if (data1.Length > 0) maxValue = Math.Max(maxValue, data1.Max());
        if (data2.Length > 0) maxValue = Math.Max(maxValue, data2.Max());

        plot.Plot.Axes.SetLimitsY(0, Math.Max(10, maxValue * 1.2));
    }

    plot.Refresh();
}

四、任務欄懸浮窗口

4.1 窗口基本設(shè)置

任務欄小窗口使用無邊框窗體,置頂顯示,不在任務欄顯示:

private void InitializeComponent()
{
    this.SuspendLayout();

    this.AutoScaleDimensions = new SizeF(7F, 17F);
    this.AutoScaleMode = AutoScaleMode.Font;
    this.ClientSize = new Size(400, 135);
    this.FormBorderStyle = FormBorderStyle.None;
    this.Name = "TaskbarWindow";
    this.TopMost = true;
    this.ShowInTaskbar = false;
    this.StartPosition = FormStartPosition.Manual;
    this.BackColor = Color.FromArgb(30, 30, 30);

    this.ResumeLayout(false);
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x80; // WS_EX_TOOLWINDOW - 不顯示在 Alt+Tab 中
        return cp;
    }
}

4.2 三種顯示模式

小窗口支持三種顯示模式,通過右鍵菜單切換:

模式 0:CPU + 內(nèi)存圖表

private void SetupMode0_CpuMemory()
{
    _cpuPlot = new FormsPlot
    {
        Location = new Point(5, 30),
        Size = new Size(190, 100),
        BackColor = Color.FromArgb(40, 40, 40)
    };
    SetupPlot(_cpuPlot, "CPU", Color.FromArgb(0, 174, 219));
    this.Controls.Add(_cpuPlot);

    _memoryPlot = new FormsPlot
    {
        Location = new Point(205, 30),
        Size = new Size(190, 100),
        BackColor = Color.FromArgb(40, 40, 40)
    };
    SetupPlot(_memoryPlot, "內(nèi)存", Color.FromArgb(142, 68, 173));
    this.Controls.Add(_memoryPlot);
}

模式 1:溫度 + 網(wǎng)絡(luò)圖表

private void SetupMode1_TempNetwork()
{
    _tempPlot = new FormsPlot
    {
        Location = new Point(5, 30),
        Size = new Size(190, 100),
        BackColor = Color.FromArgb(40, 40, 40)
    };
    SetupPlot(_tempPlot, "溫度", Color.FromArgb(231, 76, 60));
    this.Controls.Add(_tempPlot);

    _networkPlot = new FormsPlot
    {
        Location = new Point(205, 30),
        Size = new Size(190, 100),
        BackColor = Color.FromArgb(40, 40, 40)
    };
    SetupPlot(_networkPlot, "網(wǎng)絡(luò)", Color.FromArgb(52, 152, 219));
    this.Controls.Add(_networkPlot);
}

模式 2:詳細信息列表

private void SetupMode2_DetailedInfo()
{
    int yPos = 30;
    int labelHeight = 13;

    var labels = new[]
    {
        ("CPU使用率", "0%"),
        ("CPU頻率", "0 MHz"),
        ("CPU溫度", "0°C"),
        ("GPU使用率", "0%"),
        ("GPU溫度", "0°C"),
        ("內(nèi)存使用率", "0%"),
        ("網(wǎng)絡(luò)上傳", "0 KB/s"),
        ("網(wǎng)絡(luò)下載", "0 KB/s")
    };

    foreach (var (name, value) in labels)
    {
        var nameLabel = new Label
        {
            Text = name + ":",
            Location = new Point(10, yPos),
            Size = new Size(100, labelHeight),
            ForeColor = Color.FromArgb(200, 200, 200),
            Font = new Font("Microsoft YaHei UI", 8F),
            TextAlign = ContentAlignment.MiddleLeft
        };
        this.Controls.Add(nameLabel);

        var valueLabel = new Label
        {
            Text = value,
            Location = new Point(120, yPos),
            Size = new Size(270, labelHeight),
            ForeColor = Color.White,
            Font = new Font("Microsoft YaHei UI", 8F, FontStyle.Bold),
            TextAlign = ContentAlignment.MiddleLeft,
            Tag = name // 用于在更新時識別標簽
        };
        this.Controls.Add(valueLabel);

        yPos += labelHeight;
    }
}

4.3 窗口拖拽功能

實現(xiàn)窗口拖拽移動:

private Point _dragStartPoint;
private bool _isDragging = false;

private void TaskbarWindow_MouseDown(object? sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        _isDragging = true;
        _dragStartPoint = e.Location;
    }
}

private void TaskbarWindow_MouseMove(object? sender, MouseEventArgs e)
{
    if (_isDragging)
    {
        Point newLocation = this.Location;
        newLocation.X += e.X - _dragStartPoint.X;
        newLocation.Y += e.Y - _dragStartPoint.Y;
        this.Location = newLocation;
    }

    if (e.Button == MouseButtons.None)
    {
        _isDragging = false;
    }
}

4.4 右鍵菜單切換模式

private void SetupContextMenu()
{
    var contextMenu = new ContextMenuStrip();
    var modeMenu = new ToolStripMenuItem("切換顯示模式");

    var mode0 = new ToolStripMenuItem("CPU + 內(nèi)存圖表")
    {
        Checked = _displayMode == 0
    };
    mode0.Click += (s, e) => SwitchDisplayMode(0);

    var mode1 = new ToolStripMenuItem("溫度 + 網(wǎng)絡(luò)圖表")
    {
        Checked = _displayMode == 1
    };
    mode1.Click += (s, e) => SwitchDisplayMode(1);

    var mode2 = new ToolStripMenuItem("詳細信息列表")
    {
        Checked = _displayMode == 2
    };
    mode2.Click += (s, e) => SwitchDisplayMode(2);

    modeMenu.DropDownItems.Add(mode0);
    modeMenu.DropDownItems.Add(mode1);
    modeMenu.DropDownItems.Add(mode2);

    contextMenu.Items.Add(modeMenu);
    contextMenu.Items.Add(new ToolStripSeparator());
    contextMenu.Items.Add("關(guān)閉", null, (s, e) => this.Close());

    this.ContextMenuStrip = contextMenu;
}

private void SwitchDisplayMode(int mode)
{
    _displayMode = mode;
    _settings.TaskbarWindowDisplayMode = mode;

    // 保存配置
    Utils.SettingsManager.Save(_settings);

    // 重新創(chuàng)建界面
    SetupWindow();
}

五、配置持久化

5.1 配置數(shù)據(jù)結(jié)構(gòu)

public class AppSettings
{
    public bool AutoStart { get; set; } = false;
    public int RefreshInterval { get; set; } = 1000;
    public bool ShowTaskbarWindow { get; set; } = true;
    public int TaskbarWindowX { get; set; } = -1;
    public int TaskbarWindowY { get; set; } = -1;
    public int HistoryDuration { get; set; } = 120;
    public bool StartMinimized { get; set; } = false;
    public bool EnableTemperatureMonitoring { get; set; } = true;
    public int MainWindowWidth { get; set; } = 900;
    public int MainWindowHeight { get; set; } = 600;
    public int TaskbarWindowDisplayMode { get; set; } = 0;
}

5.2 JSON 序列化存儲

public static class SettingsManager
{
    private static readonly string SettingsPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
        "WindowsMonitor",
        "settings.json"
    );

    public static AppSettings Load()
    {
        try
        {
            if (File.Exists(SettingsPath))
            {
                string json = File.ReadAllText(SettingsPath);
                return JsonSerializer.Deserialize<AppSettings>(json) ?? new AppSettings();
            }
        }
        catch { }

        return new AppSettings();
    }

    public static void Save(AppSettings settings)
    {
        try
        {
            string directory = Path.GetDirectoryName(SettingsPath)!;
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            var options = new JsonSerializerOptions { WriteIndented = true };
            string json = JsonSerializer.Serialize(settings, options);
            File.WriteAllText(SettingsPath, json);
        }
        catch { }
    }

    public static string GetSettingsPath() => SettingsPath;
}

六、開機自啟動

6.1 注冊表方式實現(xiàn)

public static class AutoStartManager
{
    private const string RegistryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
    private const string AppName = "WindowsMonitor";

    public static void SetAutoStart(bool enable)
    {
        try
        {
            using var key = Registry.CurrentUser.OpenSubKey(RegistryKey, true);
            if (key == null) return;

            if (enable)
            {
                string exePath = Application.ExecutablePath;
                key.SetValue(AppName, $"\"{exePath}\"");
            }
            else
            {
                key.DeleteValue(AppName, false);
            }
        }
        catch { }
    }

    public static bool IsAutoStartEnabled()
    {
        try
        {
            using var key = Registry.CurrentUser.OpenSubKey(RegistryKey, false);
            return key?.GetValue(AppName) != null;
        }
        catch
        {
            return false;
        }
    }
}

七、UI 布局優(yōu)化

7.1 避免控件重疊

在 WinForms 中,控件重疊是常見問題。需要精確計算每個控件的位置和大小:

// 使用固定列位置和行位置
int col1X = 15, col2X = 250, col3X = 485, col4X = 720;
int row1Y = 10, row2Y = 40, row3Y = 70, row4Y = 100;

// 創(chuàng)建信息標簽時使用固定大小
private Label CreateInfoLabel(string text, Point location, Panel parent)
{
    var label = new Label
    {
        Text = text,
        Location = location,
        Size = new Size(210, 25),  // 固定寬度避免顯示不全
        AutoSize = false,
        Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular),
        AutoEllipsis = true  // 文字太長時顯示省略號
    };
    parent.Controls.Add(label);
    return label;
}

7.2 響應式布局

使用 Anchor 屬性實現(xiàn)窗口大小改變時控件自適應:

var dataPanel = new Panel
{
    Location = new Point(10, 10),
    Size = new Size(this.ClientSize.Width - 40, 140),
    BackColor = Color.White,
    BorderStyle = BorderStyle.FixedSingle,
    Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
};

八、系統(tǒng)托盤功能

8.1 托盤圖標和菜單

private void SetupNotifyIcon()
{
    _notifyIcon = new NotifyIcon
    {
        Icon = SystemIcons.Application,
        Visible = true,
        Text = "Windows 系統(tǒng)監(jiān)控"
    };

    var contextMenu = new ContextMenuStrip();
    contextMenu.Items.Add("顯示主窗口", null, (s, e) => ShowMainWindow());
    contextMenu.Items.Add("任務欄窗口", null, (s, e) => ToggleTaskbarWindow());
    contextMenu.Items.Add(new ToolStripSeparator());
    contextMenu.Items.Add("退出", null, (s, e) => Application.Exit());

    _notifyIcon.ContextMenuStrip = contextMenu;
    _notifyIcon.DoubleClick += (s, e) => ShowMainWindow();
}

8.2 窗口最小化到托盤

private void MainWindow_Resize(object? sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized)
    {
        this.Hide();
    }
}

private void MainWindow_FormClosing(object? sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;
        this.WindowState = FormWindowState.Minimized;
        this.Hide();
    }
}

總結(jié)

這個系統(tǒng)監(jiān)控工具的開發(fā)涉及了以下幾個關(guān)鍵技術(shù)點:

  1. 硬件數(shù)據(jù)采集:結(jié)合 PerformanceCounter 和 LibreHardwareMonitor 實現(xiàn)全面的硬件監(jiān)控
  2. 數(shù)據(jù)可視化:使用 ScottPlot 實現(xiàn)高性能的實時曲線繪制
  3. UI 設(shè)計:WinForms 布局優(yōu)化,避免控件重疊
  4. 數(shù)據(jù)管理:使用隊列管理歷史數(shù)據(jù),控制內(nèi)存占用
  5. 配置持久化:JSON 序列化存儲用戶配置
  6. 系統(tǒng)集成:托盤圖標、開機自啟、懸浮窗口等系統(tǒng)功能

整個項目代碼結(jié)構(gòu)清晰,模塊化設(shè)計良好,后續(xù)可以方便地擴展更多監(jiān)控項和功能。

運行截圖

主窗口展示了多個實時曲線圖表,任務欄小窗口可以自由拖拽并切換顯示模式,整體界面簡潔美觀,性能開銷低。

開發(fā)環(huán)境要求

  • Visual Studio 2022 或更高版本
  • .NET 10.0 SDK
  • Windows 10/11 操作系統(tǒng)

依賴包

<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.3" />
<PackageReference Include="ScottPlot.WinForms" Version="5.0.47" />

以上就是基于C# WinForms開發(fā)的Windows系統(tǒng)監(jiān)控工具的詳細內(nèi)容,更多關(guān)于C# WinForms Windows系統(tǒng)監(jiān)控的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Winform動態(tài)加載TabControl用法實例

    Winform動態(tài)加載TabControl用法實例

    這篇文章主要介紹了Winform動態(tài)加載TabControl用法,以實例形式詳細講述了Winform動態(tài)加載TabControl的方法,在C#應用程序開發(fā)中具有一定的實用價值,需要的朋友可以參考下
    2014-11-11
  • C#實現(xiàn)實體類與字符串互相轉(zhuǎn)換的方法

    C#實現(xiàn)實體類與字符串互相轉(zhuǎn)換的方法

    這篇文章主要介紹了C#實現(xiàn)實體類與字符串互相轉(zhuǎn)換的方法,涉及C#字符串及對象的相互轉(zhuǎn)換技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#使用linq語句查詢數(shù)組中以特定字符開頭元素的方法

    C#使用linq語句查詢數(shù)組中以特定字符開頭元素的方法

    這篇文章主要介紹了C#使用linq語句查詢數(shù)組中以特定字符開頭元素的方法,涉及C#使用linq進行查詢的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • C#計算代碼執(zhí)行時間的方法

    C#計算代碼執(zhí)行時間的方法

    在一些測試工作時我們需要獲得高精度的代碼執(zhí)行時間以比較其效率。
    2013-03-03
  • Unity3d獲取系統(tǒng)時間

    Unity3d獲取系統(tǒng)時間

    本文通過一段代碼給大家詳解unity3d獲取系統(tǒng)時間,代碼簡單易懂,小伙伴們快來看看吧
    2015-11-11
  • C#設(shè)計模式之外觀模式介紹

    C#設(shè)計模式之外觀模式介紹

    外觀模式:為子系統(tǒng)中的一組接口提供一個一致的界面,此模式定義了一個高層的接口,這個借口使得這子系統(tǒng)容易使用
    2012-10-10
  • C#實現(xiàn)清除IE瀏覽器緩存的方法

    C#實現(xiàn)清除IE瀏覽器緩存的方法

    這篇文章主要介紹了C#實現(xiàn)清除IE瀏覽器緩存的方法,實例分析了C#針對瀏覽器緩存清理所涉及的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#使用Spire.Doc自動化插入圖片到Word文檔

    C#使用Spire.Doc自動化插入圖片到Word文檔

    還在為 Word 文檔中圖片的手動插入而煩惱嗎?無論是生成批量報告、合同模板,還是動態(tài)展示數(shù)據(jù),程序化地將圖片嵌入Word文檔都是開發(fā)者們常常面臨的挑戰(zhàn),本文將深入探討如何利用強大的第三方庫 Spire.Doc for .NET,在C#項目中高效、靈活地實現(xiàn)Word文檔的圖片插入
    2026-02-02
  • c#高效的線程安全隊列ConcurrentQueue<T>的實現(xiàn)

    c#高效的線程安全隊列ConcurrentQueue<T>的實現(xiàn)

    這篇文章主要介紹了c#高效的線程安全隊列ConcurrentQueue<T>的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • C#實現(xiàn)簡單的二叉查找樹

    C#實現(xiàn)簡單的二叉查找樹

    這篇文章介紹了C#實現(xiàn)二叉查找樹的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06

最新評論

巩留县| 神池县| 墨江| 中方县| 彰化市| 鄂托克旗| 犍为县| 婺源县| 忻州市| 泸水县| 宣恩县| 林口县| 扶绥县| 汉沽区| 兴国县| 南华县| 天长市| 汕尾市| 汾西县| 长岭县| 宜昌市| 抚松县| 高碑店市| 托克托县| 射洪县| 武冈市| 临汾市| 曲松县| 容城县| 镇坪县| 德令哈市| 鸡东县| 科技| 清水县| 贵德县| 朔州市| 格尔木市| 阿拉尔市| 中江县| 扬州市| 平湖市|