Skip to content

Commit 018e9eb

Browse files
committed
Fix: crash if found new io device
1 parent ae2aa95 commit 018e9eb

File tree

6 files changed

+125
-106
lines changed

6 files changed

+125
-106
lines changed

Hardware/Hardware.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="LibreHardwareMonitorLib" Version="0.8.9-pre46" />
12+
<PackageReference Include="LibreHardwareMonitorLib" Version="0.8.9-pre47" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

Hardware/Windows/DeviceIoInfo/DeviceInfo.cs

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,79 +14,77 @@ public static class DeviceInfo
1414
public static float ReadIO { get; private set; }
1515
public static float WriteIO { get; private set; }
1616

17-
public static List<Device> LogicalDrives { get; private set; }
18-
private static Dictionary<string, DeviceIoControl> DeviceIoList;
19-
private static int CountDiscs = 0;
20-
21-
private static Performance[] Perfomances;
22-
private static float[] PrevReadValues;
23-
private static float[] PrevWriteValues;
24-
25-
private static void SetDiscCollection()
17+
public static List<Device> LogicalDrives { get; }
18+
private static Dictionary<string, DeviceIoControl> _deviceIoList;
19+
20+
private static Performance[] _perfomances;
21+
private static float[] _prevReadValues;
22+
private static float[] _prevWriteValues;
23+
24+
static DeviceInfo()
2625
{
2726
LogicalDrives = new();
28-
DeviceIoList = new();
29-
30-
IEnumerable<LogicalDrive> logicalDevicesIO = DeviceIoControl.GetLogicalDrives();
31-
32-
CountDiscs = logicalDevicesIO.Count();
27+
_deviceIoList = new();
28+
}
3329

34-
byte index = 0;
30+
private static void SetDiscCollection()
31+
{
32+
LogicalDrives.Clear();
33+
_deviceIoList.Clear();
3534

36-
PrevReadValues = new float[logicalDevicesIO.Count()];
37-
PrevWriteValues = new float[PrevReadValues.Length];
38-
Perfomances = new Performance[PrevReadValues.Length];
35+
IEnumerable<LogicalDrive> logicalDevicesIo = DeviceIoControl.GetLogicalDrives();
3936

40-
foreach (LogicalDrive logical in logicalDevicesIO)
37+
foreach (LogicalDrive logical in logicalDevicesIo)
4138
{
42-
if (logical.Type != WinApi.DRIVE.FIXED) continue;
43-
44-
DeviceIoControl deviceIO = new(logical.Name);
45-
46-
// if (!deviceIO.FileSystem.IsVolumeMounted || deviceIO.Storage.MediaTypesEx.DeviceType != StorageApi.STORAGE_DEVICE_NUMBER.FileDevice.DISK)
47-
// {
48-
// deviceIO.Dispose();
49-
// continue;
50-
// }
39+
if (logical.Type != WinApi.DRIVE.FIXED)
40+
continue;
5141

5242
Device device = new();
5343
device.Letter = logical.Name;
5444

55-
var smart = deviceIO.Disc.Smart;
45+
LogicalDrives.Add(device);
46+
_deviceIoList.Add(device.Letter, new DeviceIoControl(device.Letter));
47+
}
5648

57-
if (smart != null) device.Model = smart.SystemParams.ModelNumber;
58-
else device.Model = new DriveInfo(logical.Name).VolumeLabel;
49+
byte index = 0;
5950

60-
if (device.Model.Contains("samsung", StringComparison.OrdinalIgnoreCase)) device.Vendor = VendorEnum.Samsung;
61-
else if (device.Model.Contains("kingston", StringComparison.OrdinalIgnoreCase)) device.Vendor = VendorEnum.Kingston;
62-
else if (device.Model.Contains("wdc", StringComparison.OrdinalIgnoreCase)) device.Vendor = VendorEnum.WDC;
63-
else device.Vendor = VendorEnum.Other;
51+
_prevReadValues = new float[LogicalDrives.Count];
52+
_prevWriteValues = new float[LogicalDrives.Count];
53+
_perfomances = new Performance[LogicalDrives.Count];
6454

65-
LogicalDrives.Add(device);
55+
foreach (Device dev in LogicalDrives)
56+
{
57+
var smart = _deviceIoList[dev.Letter].Disc.Smart;
6658

67-
DeviceIoList.Add(device.Letter, deviceIO);
59+
if (smart != null) dev.Model = smart.SystemParams.ModelNumber.Trim(' ');
60+
else dev.Model = new DriveInfo(dev.Letter).VolumeLabel;
6861

69-
Perfomances[index] = deviceIO.Disc.GetDiscPerformance();
62+
if (dev.Model.Contains("samsung", StringComparison.OrdinalIgnoreCase)) dev.Vendor = VendorEnum.Samsung;
63+
else if (dev.Model.Contains("kingston", StringComparison.OrdinalIgnoreCase)) dev.Vendor = VendorEnum.Kingston;
64+
else if (dev.Model.Contains("wdc", StringComparison.OrdinalIgnoreCase)) dev.Vendor = VendorEnum.WDC;
65+
else dev.Vendor = VendorEnum.Other;
66+
67+
_perfomances[index] = _deviceIoList[dev.Letter].Disc.GetDiscPerformance();
7068

71-
DiscApi.DISK_PERFORMANCE dISK_PERFORMANCE = Perfomances[index].QueryPerformanceInfo();
69+
DiscApi.DISK_PERFORMANCE diskPerformance = _perfomances[index].QueryPerformanceInfo();
7270

73-
PrevReadValues[index] = dISK_PERFORMANCE.BytesRead;
74-
PrevWriteValues[index] = dISK_PERFORMANCE.BytesWritten;
71+
_prevReadValues[index] = diskPerformance.BytesRead;
72+
_prevWriteValues[index] = diskPerformance.BytesWritten;
7573

7674
index++;
7775
}
7876
}
7977

8078
public static bool IsUpdateDiscs()
8179
{
82-
if (CountDiscs != DeviceIoControl.GetLogicalDrives().Count())
80+
if (LogicalDrives.Count != DeviceIoControl.GetLogicalDrives().Count())
8381
{
8482
SetDiscCollection();
8583

8684
return true;
8785
}
88-
else
89-
return false;
86+
87+
return false;
9088
}
9189

9290
public static void UpdateSizeOfDiscs()
@@ -96,10 +94,17 @@ public static void UpdateSizeOfDiscs()
9694
foreach (Device logic in LogicalDrives)
9795
{
9896
DriveInfo drive = new(logic.Letter);
99-
logic.TotalSpace = drive.TotalSize;
100-
logic.FreeSpace = drive.TotalFreeSpace;
101-
logic.UsedSpace = drive.TotalSize - drive.AvailableFreeSpace;
102-
logic.PercentUsedSpace = Convert.ToByte(logic.UsedSpace / (logic.TotalSpace / 100));
97+
try
98+
{
99+
logic.TotalSpace = drive.TotalSize;
100+
logic.FreeSpace = drive.TotalFreeSpace;
101+
logic.UsedSpace = drive.TotalSize - drive.AvailableFreeSpace;
102+
logic.PercentUsedSpace = Convert.ToByte(logic.UsedSpace / (logic.TotalSpace / 100));
103+
}
104+
catch (DriveNotFoundException)
105+
{
106+
throw new DriveNotFoundException();
107+
}
103108
}
104109
}
105110

@@ -109,7 +114,7 @@ public static void UpdateInfoOfDiscs()
109114

110115
foreach (Device logical in LogicalDrives)
111116
{
112-
SmartInfoCollection smart = DeviceIoList[logical.Letter].Disc.Smart;
117+
SmartInfoCollection smart = _deviceIoList[logical.Letter].Disc.Smart;
113118

114119
if (smart != null)
115120
{
@@ -135,23 +140,23 @@ public static void UpdateInfoOfDiscs()
135140

136141
public static void PerfomanceDiskUpdate(byte index)
137142
{
138-
DiscApi.DISK_PERFORMANCE dISK_PERFORMANCE = Perfomances[index].QueryPerformanceInfo();
143+
DiscApi.DISK_PERFORMANCE dISK_PERFORMANCE = _perfomances[index].QueryPerformanceInfo();
139144

140-
ReadIO = (dISK_PERFORMANCE.BytesRead - PrevReadValues[index]) / 1000000;
141-
WriteIO = (dISK_PERFORMANCE.BytesWritten - PrevWriteValues[index]) / 1000000;
145+
ReadIO = (dISK_PERFORMANCE.BytesRead - _prevReadValues[index]) / 1000000;
146+
WriteIO = (dISK_PERFORMANCE.BytesWritten - _prevWriteValues[index]) / 1000000;
142147

143-
PrevReadValues[index] = dISK_PERFORMANCE.BytesRead;
144-
PrevWriteValues[index] = dISK_PERFORMANCE.BytesWritten;
148+
_prevReadValues[index] = dISK_PERFORMANCE.BytesRead;
149+
_prevWriteValues[index] = dISK_PERFORMANCE.BytesWritten;
145150
}
146151

147152
public static void Close()
148153
{
149-
foreach (Performance performance in Perfomances)
154+
foreach (Performance performance in _perfomances)
150155
{
151156
performance?.Dispose();
152157
}
153158

154-
foreach (DeviceIoControl device in DeviceIoList.Values)
159+
foreach (DeviceIoControl device in _deviceIoList.Values)
155160
{
156161
device.Dispose();
157162
}
Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,66 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
4+
using System.IO;
5+
using System.Reactive.Linq;
46
using Avalonia.Controls;
7+
using DynamicData;
58
using Hardware.Windows.DeviceIoInfo;
69
using LiveChartsCore.SkiaSharpView.Painting;
7-
using SkiaSharp;
10+
using ReactiveUI;
811
using SysMonAvalonia.Data;
912

1013
namespace SysMonAvalonia.Models
1114
{
1215
public class DeviceIoModel : IDisposable
1316
{
14-
public ObservableCollection<DeviceIoData> DeviceCollection { get; set; } = new();
17+
private readonly SourceList<DeviceIoData> _deviceList;
18+
public ReadOnlyObservableCollection<DeviceIoData> DeviceCollection;
19+
20+
public DeviceIoModel()
21+
{
22+
_deviceList = new();
23+
_deviceList.Connect().ObserveOn(RxApp.MainThreadScheduler).Bind(out DeviceCollection).Subscribe();
24+
}
1525

1626
public void UpdateDeviceCollection()
1727
{
1828
if (DeviceInfo.IsUpdateDiscs())
1929
{
30+
UpdateDeviceSpace();
31+
2032
List<Device> devices = DeviceInfo.LogicalDrives;
2133

22-
RemoveOldDeviceInCollection(devices);
34+
if (_deviceList.Count > devices.Count)
35+
RemoveOldDeviceInCollection(devices);
2336

2437
foreach (Device dev in devices)
2538
{
2639
if (ExistDeviceInCollection(dev)) continue;
2740

2841
DeviceIoData device = new();
29-
device.Model = dev.Model.Trim(' ');
42+
device.Model = dev.Model;
3043
device.Letter = dev.Letter;
3144
device.DeviceChart.Fill = App.Current.FindResource("DeviceChartFill") as SolidColorPaint;
32-
DeviceCollection.Add(device);
45+
46+
_deviceList.Add(device);
3347
}
3448
}
3549
}
3650

3751
public void UpdateDeviceSpace()
3852
{
39-
DeviceInfo.UpdateSizeOfDiscs();
53+
try
54+
{
55+
DeviceInfo.UpdateSizeOfDiscs();
56+
}
57+
catch (DriveNotFoundException)
58+
{
59+
UpdateDeviceCollection();
60+
DeviceInfo.UpdateSizeOfDiscs();
61+
}
4062

41-
foreach (DeviceIoData devData in DeviceCollection)
63+
foreach (DeviceIoData devData in _deviceList.Items)
4264
{
4365
foreach (Device dev in DeviceInfo.LogicalDrives)
4466
{
@@ -58,7 +80,7 @@ public void UpdateDeviceInfo()
5880
{
5981
DeviceInfo.UpdateInfoOfDiscs();
6082

61-
foreach (DeviceIoData devData in DeviceCollection)
83+
foreach (DeviceIoData devData in _deviceList.Items)
6284
{
6385
foreach (Device dev in DeviceInfo.LogicalDrives)
6486
{
@@ -76,58 +98,58 @@ public void UpdateDeviceInfo()
7698

7799
public void UpdatePerformance()
78100
{
79-
for (byte b = 0; b < DeviceCollection.Count; b++)
101+
byte count = 0;
102+
103+
foreach (DeviceIoData dId in _deviceList.Items)
80104
{
81-
DeviceInfo.PerfomanceDiskUpdate(b);
105+
DeviceInfo.PerfomanceDiskUpdate(count);
82106

83-
DeviceCollection[b].ReadIO = DeviceInfo.ReadIO;
84-
DeviceCollection[b].WriteIO = DeviceInfo.WriteIO;
85-
DeviceCollection[b].DeviceChart.Value = DeviceInfo.ReadIO + DeviceInfo.WriteIO;
107+
dId.ReadIO = DeviceInfo.ReadIO;
108+
dId.WriteIO = DeviceInfo.WriteIO;
109+
dId.DeviceChart.Value = DeviceInfo.ReadIO + DeviceInfo.WriteIO;
110+
111+
count++;
86112
}
87113
}
88114

89115
private bool ExistDeviceInCollection(Device device)
90116
{
91-
bool isExist = false;
92-
93-
foreach (DeviceIoData dev in DeviceCollection)
117+
foreach (DeviceIoData dID in _deviceList.Items)
94118
{
95-
if (dev.Model.Contains(device.Model) && dev.TotalSize == device.TotalSpace)
96-
{
97-
isExist = true;
98-
break;
99-
}
119+
if (dID.Model.Contains(device.Model) && dID.TotalSize == device.TotalSpace)
120+
return true;
100121
}
101122

102-
return isExist;
123+
return false;
103124
}
104125

105126
private void RemoveOldDeviceInCollection(List<Device> device)
106127
{
107-
int countCollection = DeviceCollection.Count;
128+
byte index = 0;
108129

109-
for (byte b = 0; b < countCollection; b++)
130+
foreach (DeviceIoData item in _deviceList.Items)
110131
{
111-
bool isExist = true;
132+
bool isExist = false;
112133

113134
foreach (Device dev in device)
114135
{
115-
if (dev.Model.Contains(DeviceCollection[b].Model) && dev.TotalSpace == DeviceCollection[b].TotalSize)
116-
isExist = false;
136+
if (dev.Model.Contains(item.Model) && dev.TotalSpace == item.TotalSize)
137+
{
138+
isExist = true;
139+
break;
140+
}
117141
}
118142

119-
if (isExist)
120-
{
121-
DeviceCollection.RemoveAt(b);
122-
countCollection--;
123-
}
143+
if (!isExist) _deviceList.RemoveAt(index);
144+
145+
index++;
124146
}
125147
}
126148

127149
public void Dispose()
128150
{
129151
DeviceInfo.Close();
130-
DeviceCollection.Clear();
152+
_deviceList.Dispose();
131153
}
132154
}
133155
}

SysMonAvalonia/SysMonAvalonia.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
<None Remove="Assets\Styles\Light.xaml" />
2121
</ItemGroup>
2222
<ItemGroup>
23-
<PackageReference Include="Avalonia" Version="0.10.7" />
24-
<PackageReference Include="Avalonia.Desktop" Version="0.10.7" />
25-
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.7" />
26-
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.7" />
27-
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.7.1" />
23+
<PackageReference Include="Avalonia" Version="0.10.8" />
24+
<PackageReference Include="Avalonia.Desktop" Version="0.10.8" />
25+
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.8" />
26+
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.8" />
27+
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.8" />
2828
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-beta.71" />
2929
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
3030
<PackageReference Include="Projektanker.Icons.Avalonia" Version="3.1.2" />

0 commit comments

Comments
 (0)