WMI queries do not have a timeout by default and can subsequently hang. This commit adds timeouts to avoid these hangs. On timeout, `Get` will throw a `ManagementException` that has an error code of `ManagementStatus.Timedout`. In the case of abstract storage, this exception will be silently swallowed and the statistics from WMI not updated until the next update interval, which seems appropriate. The storage group, on the other hand, a timeout there would cause an initialization exception which would be propagated up to the caller (which seems ok as something must be terribly wrong for that WMI query to fail). The code was also updated to call dispose for all the WMI objects. I don't see this causing a behavior difference, but I found it better to be safe than sorry. The timeouts were chosen to be a compromise between returning in a reasonable timeframe and allowing WMI, which can be terribly slow, to return the query.
60 lines
2.2 KiB
C#
60 lines
2.2 KiB
C#
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
// Copyright (C) LibreHardwareMonitor and Contributors.
|
|
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
|
|
// All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Management;
|
|
|
|
namespace LibreHardwareMonitor.Hardware.Storage
|
|
{
|
|
internal class StorageGroup : IGroup
|
|
{
|
|
private readonly List<AbstractStorage> _hardware = new List<AbstractStorage>();
|
|
|
|
public StorageGroup(ISettings settings)
|
|
{
|
|
if (Software.OperatingSystem.IsUnix)
|
|
return;
|
|
|
|
//https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive
|
|
string query = "SELECT * FROM Win32_DiskDrive";
|
|
using (var mosDisks = new ManagementObjectSearcher(query) {Options = {Timeout = TimeSpan.FromSeconds(10)}})
|
|
using (ManagementObjectCollection queryCollection = mosDisks.Get())
|
|
{
|
|
foreach (ManagementBaseObject disk in queryCollection)
|
|
{
|
|
string deviceId = (string)disk.Properties["DeviceId"].Value; // is \\.\PhysicalDrive0..n
|
|
uint idx = Convert.ToUInt32(disk.Properties["Index"].Value);
|
|
ulong diskSize = Convert.ToUInt64(disk.Properties["Size"].Value);
|
|
int scsi = Convert.ToInt32(disk.Properties["SCSIPort"].Value);
|
|
|
|
if (deviceId != null)
|
|
{
|
|
var instance = AbstractStorage.CreateInstance(deviceId, idx, diskSize, scsi, settings);
|
|
if (instance != null)
|
|
{
|
|
_hardware.Add(instance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public IReadOnlyList<IHardware> Hardware => _hardware;
|
|
|
|
public string GetReport()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
foreach (AbstractStorage storage in _hardware)
|
|
storage.Close();
|
|
}
|
|
}
|
|
}
|