3 Commits

Author SHA1 Message Date
afa7bd987a Update LibreHardwareMonitor
All checks were successful
Deploy to Gitea Releases / deploy-to-gitea-releases (push) Successful in 3m10s
- Some nullability updates
2026-02-27 13:46:06 -05:00
4cd7e74923 Minor change to test upgrade
All checks were successful
Deploy to Gitea Releases / deploy-to-gitea-releases (push) Successful in 52s
2026-01-27 21:25:59 -05:00
d65c556656 Try stopping service task before upgrade/uninstall
All checks were successful
Deploy to Gitea Releases / deploy-to-gitea-releases (push) Successful in 54s
2026-01-27 21:20:35 -05:00
12 changed files with 86 additions and 41 deletions

View File

@@ -11,9 +11,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.5" /> <PackageReference Include="LibreHardwareMonitorLib" Version="0.9.6" />
<PackageReference Include="PipeMethodCalls" Version="4.0.3" /> <PackageReference Include="PipeMethodCalls" Version="4.0.3" />
<PackageReference Include="Serilog" Version="4.3.0" /> <PackageReference Include="Serilog" Version="4.3.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="TaskScheduler" Version="2.12.2" /> <PackageReference Include="TaskScheduler" Version="2.12.2" />
</ItemGroup> </ItemGroup>

View File

@@ -8,7 +8,7 @@ namespace HardwareMonitorStatusWindow.StatusWindow;
public partial class App public partial class App
{ {
private List<IDisposable> _windowSourceList; private List<IDisposable>? _windowSourceList;
protected override void OnStartup(StartupEventArgs e) protected override void OnStartup(StartupEventArgs e)
{ {
@@ -30,7 +30,7 @@ public partial class App
protected override void OnExit(ExitEventArgs e) protected override void OnExit(ExitEventArgs e)
{ {
_windowSourceList.ForEach(ws => ws.Dispose()); _windowSourceList?.ForEach(ws => ws.Dispose());
base.OnExit(e); base.OnExit(e);
} }

View File

@@ -6,15 +6,16 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Serilog;
namespace HardwareMonitorStatusWindow.StatusWindow; namespace HardwareMonitorStatusWindow.StatusWindow;
internal static class Data internal static class Data
{ {
private static PipeClient<IHardwareMonitorService> _pipeClient; private static PipeClient<IHardwareMonitorService>? _pipeClient;
private static IEnumerable<Hardware> _hardware; private static IEnumerable<Hardware>? _hardware;
internal static ObservableCollection<SensorEntry> SensorEntries { get; set; } internal static ObservableCollection<SensorEntry> SensorEntries { get; set; } = [];
internal static async Task LoadComputer() internal static async Task LoadComputer()
{ {
@@ -25,7 +26,7 @@ internal static class Data
} }
catch (Exception exception) catch (Exception exception)
{ {
Log.Error(exception, "");
} }
} }
@@ -36,14 +37,14 @@ internal static class Data
internal static void CloseComputer() internal static void CloseComputer()
{ {
_pipeClient.Dispose(); _pipeClient?.Dispose();
} }
internal static IList<Hardware> ComputerHardware => _hardware.ToList(); internal static IList<Hardware> ComputerHardware => _hardware?.ToList() ?? [];
internal static void Load() internal static void Load()
{ {
SensorEntries = JsonSerializer.Deserialize<ObservableCollection<SensorEntry>>(Settings.Default.Sensors); SensorEntries = JsonSerializer.Deserialize<ObservableCollection<SensorEntry>>(Settings.Default.Sensors) ?? [];
} }
internal static void Save() internal static void Save()

View File

@@ -7,15 +7,18 @@ namespace HardwareMonitorStatusWindow.StatusWindow;
internal class DataErrorDictionary : Dictionary<string, List<string>> internal class DataErrorDictionary : Dictionary<string, List<string>>
{ {
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
private void OnErrorsChanged(string propertyName) private void OnErrorsChanged(string propertyName)
{ {
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
} }
public IEnumerable GetErrors(string propertyName) public IEnumerable? GetErrors(string? propertyName)
{ {
if (propertyName == null)
return null;
return TryGetValue(propertyName, out var value) ? value : null; return TryGetValue(propertyName, out var value) ? value : null;
} }

View File

@@ -1,4 +1,6 @@
using Serilog; using HardwareMonitorStatusWindow.Service;
using Microsoft.Win32.TaskScheduler;
using Serilog;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Velopack; using Velopack;
@@ -17,7 +19,30 @@ internal class Program
Log.Information("Start"); Log.Information("Start");
VelopackApp.Build().SetLogger(new SerilogVelopackLogger()).Run(); var stopServiceHook = new VelopackHook(_ =>
{
try
{
using var taskService = new TaskService();
Log.Information("Checking for task name: {name}", HardwareMonitorService.ScheduledTaskName);
var existingTask = taskService.FindTask(HardwareMonitorService.ScheduledTaskName);
Log.Information("Task: {existingTask}", existingTask);
Log.Information("Stopping task");
existingTask?.Stop();
}
catch (Exception exception)
{
// Ignored
Log.Error(exception, "");
}
});
VelopackApp.Build().OnBeforeUpdateFastCallback(stopServiceHook).OnBeforeUninstallFastCallback(stopServiceHook).SetLogger(new SerilogVelopackLogger()).Run();
var app = new App(); var app = new App();
app.InitializeComponent(); app.InitializeComponent();

View File

@@ -11,15 +11,14 @@ namespace HardwareMonitorStatusWindow.StatusWindow;
public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
{ {
private readonly DataErrorDictionary _dataErrorDictionary; private readonly DataErrorDictionary _dataErrorDictionary = new();
public SensorEntry() public SensorEntry()
{ {
_dataErrorDictionary = new DataErrorDictionary();
_dataErrorDictionary.ErrorsChanged += DataErrorDictionaryErrorsChanged; _dataErrorDictionary.ErrorsChanged += DataErrorDictionaryErrorsChanged;
} }
public string Label public string? Label
{ {
get; get;
set set
@@ -31,7 +30,7 @@ public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
} }
} }
public string HardwareId public string? HardwareId
{ {
get; get;
set set
@@ -41,7 +40,7 @@ public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
} }
} }
public string SensorId public string? SensorId
{ {
get; get;
set set
@@ -52,7 +51,7 @@ public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
} }
[JsonIgnore] [JsonIgnore]
public Hardware? Hardware => Data.ComputerHardware.FirstOrDefault(h => h.Identifier.ToString() == HardwareId); public Hardware? Hardware => Data.ComputerHardware?.FirstOrDefault(h => h.Identifier.ToString() == HardwareId);
[JsonIgnore] [JsonIgnore]
public Sensor? Sensor => Hardware?.Sensors.FirstOrDefault(s => s.Identifier.ToString() == SensorId); public Sensor? Sensor => Hardware?.Sensors.FirstOrDefault(s => s.Identifier.ToString() == SensorId);
@@ -60,19 +59,22 @@ public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
[JsonIgnore] [JsonIgnore]
public bool HasErrors => _dataErrorDictionary.Any(); public bool HasErrors => _dataErrorDictionary.Any();
public IEnumerable GetErrors(string propertyName) public IEnumerable GetErrors(string? propertyName)
{ {
return _dataErrorDictionary.GetErrors(propertyName); if (string.IsNullOrWhiteSpace(propertyName))
throw new InvalidOperationException();
return _dataErrorDictionary.GetErrors(propertyName) ?? Enumerable.Empty<string>();
} }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
private void DataErrorDictionaryErrorsChanged(object sender, DataErrorsChangedEventArgs e) private void DataErrorDictionaryErrorsChanged(object? sender, DataErrorsChangedEventArgs e)
{ {
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(e.PropertyName)); ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(e.PropertyName));
} }
private bool ValidateLabel(string newValue) private bool ValidateLabel(string? newValue)
{ {
_dataErrorDictionary.ClearErrors(nameof(Label)); _dataErrorDictionary.ClearErrors(nameof(Label));
@@ -84,14 +86,14 @@ public class SensorEntry : INotifyDataErrorInfo, INotifyPropertyChanged
return false; return false;
} }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{ {
if (EqualityComparer<T>.Default.Equals(field, value)) return false; if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value; field = value;

View File

@@ -58,12 +58,12 @@
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<StackPanel> <StackPanel>
<TextBlock Text="{Binding Path=Hardware.Type}" <TextBlock Text="{Binding Path=Hardware.Type, FallbackValue=null}"
Height="Auto" Height="Auto"
FontSize="10" FontSize="10"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="0,2,0,2" /> Margin="0,2,0,2" />
<TextBlock Text="{Binding Path=Hardware.Name}" <TextBlock Text="{Binding Path=Hardware.Name, FallbackValue=null}"
Height="Auto" Height="Auto"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</StackPanel> </StackPanel>
@@ -75,12 +75,12 @@
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<StackPanel> <StackPanel>
<TextBlock Text="{Binding Path=Sensor.Type}" <TextBlock Text="{Binding Path=Sensor.Type, FallbackValue=null}"
Height="Auto" Height="Auto"
FontSize="10" FontSize="10"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="0,2,0,2" /> Margin="0,2,0,2" />
<TextBlock Text="{Binding Path=Sensor.Name}" <TextBlock Text="{Binding Path=Sensor.Name, FallbackValue=null}"
Height="Auto" Height="Auto"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</StackPanel> </StackPanel>

View File

@@ -7,7 +7,7 @@ namespace HardwareMonitorStatusWindow.StatusWindow.SettingsWindow;
public partial class HardwareSettingsPanel public partial class HardwareSettingsPanel
{ {
private CollectionViewSource _collectionViewSource; private CollectionViewSource? _collectionViewSource;
public HardwareSettingsPanel() public HardwareSettingsPanel()
{ {
@@ -105,7 +105,7 @@ public partial class HardwareSettingsPanel
SensorDataGrid.SelectedItems.CopyTo(selectedItems, 0); SensorDataGrid.SelectedItems.CopyTo(selectedItems, 0);
foreach (var sensorEntry in selectedItems) foreach (var sensorEntry in selectedItems)
Data.SensorEntries.Remove(sensorEntry); Data.SensorEntries?.Remove(sensorEntry);
SetSensorButtonStates(); SetSensorButtonStates();
} }

View File

@@ -12,7 +12,7 @@ public partial class SensorWindow
InitializeComponent(); InitializeComponent();
} }
public bool? Display(SensorEntry sensorEntry, Window owner) public bool? Display(SensorEntry sensorEntry, Window? owner)
{ {
DataContext = sensorEntry; DataContext = sensorEntry;

View File

@@ -1,6 +1,5 @@
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using HardwareMonitorStatusWindow.StatusWindow;
namespace HardwareMonitorStatusWindow.StatusWindow.SettingsWindow; namespace HardwareMonitorStatusWindow.StatusWindow.SettingsWindow;

View File

@@ -28,10 +28,10 @@
<PackageReference Include="ChrisKaczor.Wpf.Controls.Link" Version="1.0.4" /> <PackageReference Include="ChrisKaczor.Wpf.Controls.Link" Version="1.0.4" />
<PackageReference Include="ChrisKaczor.Wpf.Validation" Version="1.0.4" /> <PackageReference Include="ChrisKaczor.Wpf.Validation" Version="1.0.4" />
<PackageReference Include="ChrisKaczor.Wpf.Windows.CategoryWindow" Version="1.0.2" /> <PackageReference Include="ChrisKaczor.Wpf.Windows.CategoryWindow" Version="1.0.2" />
<PackageReference Include="ChrisKaczor.Wpf.Windows.FloatingStatusWindow" Version="2.0.0.7" /> <PackageReference Include="ChrisKaczor.Wpf.Windows.FloatingStatusWindow" Version="2.0.0.8" />
<PackageReference Include="gong-wpf-dragdrop" Version="4.0.0" /> <PackageReference Include="gong-wpf-dragdrop" Version="4.0.0" />
<PackageReference Include="PipeMethodCalls" Version="4.0.3" /> <PackageReference Include="PipeMethodCalls" Version="4.0.3" />
<PackageReference Include="Serilog" Version="4.3.0" /> <PackageReference Include="Serilog" Version="4.3.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Velopack" Version="0.0.1298" /> <PackageReference Include="Velopack" Version="0.0.1298" />
</ItemGroup> </ItemGroup>

View File

@@ -2,6 +2,7 @@
using ChrisKaczor.Wpf.Windows.FloatingStatusWindow; using ChrisKaczor.Wpf.Windows.FloatingStatusWindow;
using HardwareMonitorStatusWindow.Service; using HardwareMonitorStatusWindow.Service;
using HardwareMonitorStatusWindow.StatusWindow.SettingsWindow; using HardwareMonitorStatusWindow.StatusWindow.SettingsWindow;
using LibreHardwareMonitor.PawnIo;
using Microsoft.Win32.TaskScheduler; using Microsoft.Win32.TaskScheduler;
using Serilog; using Serilog;
using System; using System;
@@ -23,13 +24,24 @@ internal class WindowSource : IWindowSource, IDisposable
private readonly FloatingStatusWindow _floatingStatusWindow; private readonly FloatingStatusWindow _floatingStatusWindow;
private readonly Timer _timer; private readonly Timer _timer;
private readonly Dispatcher _dispatcher; private readonly Dispatcher _dispatcher;
internal WindowSource() internal WindowSource()
{ {
try try
{ {
using var taskService = new TaskService(); using var taskService = new TaskService();
if (!PawnIo.IsInstalled)
{
Log.Information("PawnIO not installed");
}
else
{
var pawnIoVersion = PawnIo.Version;
Log.Information("PawnIO installed: {version}", pawnIoVersion);
}
Log.Information("Checking for task name: {name}", HardwareMonitorService.ScheduledTaskName); Log.Information("Checking for task name: {name}", HardwareMonitorService.ScheduledTaskName);
var existingTask = taskService.FindTask(HardwareMonitorService.ScheduledTaskName); var existingTask = taskService.FindTask(HardwareMonitorService.ScheduledTaskName);
@@ -152,7 +164,7 @@ internal class WindowSource : IWindowSource, IDisposable
Data.Load(); Data.Load();
} }
private void Save() private static void Save()
{ {
Data.Save(); Data.Save();
} }
@@ -231,6 +243,9 @@ internal class WindowSource : IWindowSource, IDisposable
foreach (var sensorEntry in Data.SensorEntries) foreach (var sensorEntry in Data.SensorEntries)
{ {
if (sensorEntry.Sensor == null)
continue;
if (text.Length > 0) if (text.Length > 0)
text.AppendLine(); text.AppendLine();