From db23e677426446440d3e991e1108dd119293df2c Mon Sep 17 00:00:00 2001 From: Vincent Maas Date: Fri, 21 Apr 2023 20:11:20 +0200 Subject: [PATCH] fix crash and nvidia error --- ColorControl/ColorControl.csproj | 5 ++- ColorControl/MainForm.cs | 21 +++++++---- .../EventDispatcher/ProcessEventDispatcher.cs | 4 ++- ColorControl/Services/LG/LgDevice.cs | 22 ++++++++---- ColorControl/Services/LG/LgService.cs | 30 ++++++++++++---- ColorControl/Services/NVIDIA/NvDitherPanel.cs | 34 ++++++++++++++---- ColorControl/Services/NVIDIA/NvService.cs | 30 ++++++++++++++-- ColorControl/lgtv/LgTvApi.cs | 35 +++++++++++-------- ColorControl/lgtv/LgTvConnection.cs | 3 ++ NvAPIWrapper/NvAPIWrapper.csproj | 2 +- 10 files changed, 138 insertions(+), 48 deletions(-) diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index b7643dd..1d87f26 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -1,6 +1,5 @@  - 10.0 net7.0-windows10.0.20348.0 WinExe false @@ -19,8 +18,8 @@ Maassoft Maassoft 0 - 9.1.0.0 - 9.1.0.0 + 9.1.1.0 + 9.1.1.0 false true false diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index e9eb84a..ba69db4 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -792,17 +792,24 @@ NOTE: installing the service may cause a User Account Control popup."); } } - if (_nvService != null && _nvDitherPanel == null) + if (_nvService != null) { - _nvDitherPanel = new NvDitherPanel(_nvService); + if (_nvDitherPanel == null) + { + _nvDitherPanel = new NvDitherPanel(_nvService); - tabOptions.Controls.Add(_nvDitherPanel); + tabOptions.Controls.Add(_nvDitherPanel); - _nvDitherPanel.Top = grpGeneralOptions.Top; - _nvDitherPanel.Left = grpGeneralOptions.Left + grpGeneralOptions.Width + 4; - _nvDitherPanel.Width = tabOptions.Width - _nvDitherPanel.Left - 4; + _nvDitherPanel.Top = grpGeneralOptions.Top; + _nvDitherPanel.Left = grpGeneralOptions.Left + grpGeneralOptions.Width + 4; + _nvDitherPanel.Width = tabOptions.Width - _nvDitherPanel.Left - 4; - _nvDitherPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + _nvDitherPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + } + else + { + _nvDitherPanel.UpdateInfo(); + } } _initialized = false; diff --git a/ColorControl/Services/EventDispatcher/ProcessEventDispatcher.cs b/ColorControl/Services/EventDispatcher/ProcessEventDispatcher.cs index 63b1b18..41219bc 100644 --- a/ColorControl/Services/EventDispatcher/ProcessEventDispatcher.cs +++ b/ColorControl/Services/EventDispatcher/ProcessEventDispatcher.cs @@ -36,7 +36,9 @@ namespace ColorControl.Services.EventDispatcher { IsRunning = true; - var _ = CheckProcesses(); + Task.Run(async () => await CheckProcesses()); + + //var _ = CheckProcesses(); } private async Task CheckProcesses() diff --git a/ColorControl/Services/LG/LgDevice.cs b/ColorControl/Services/LG/LgDevice.cs index 52e959b..d9e3c14 100644 --- a/ColorControl/Services/LG/LgDevice.cs +++ b/ColorControl/Services/LG/LgDevice.cs @@ -263,7 +263,7 @@ namespace ColorControl.Services.LG ~LgDevice() { - _powerOffTimer?.Dispose(); + ClearPowerOffTask(); } private void AddInvokableAction(string name, Func, bool> function) @@ -780,9 +780,9 @@ namespace ColorControl.Services.LG return await _lgTvApi.GetApps(force); } - internal async Task PowerOff(bool checkHdmi = false) + internal async Task PowerOff(bool checkHdmi = false, bool reconnect = true) { - if (!await Connected(true) || CurrentState != PowerState.Active) + if (!await Connected(reconnect) || CurrentState != PowerState.Active) { return false; } @@ -1102,15 +1102,25 @@ namespace ColorControl.Services.LG internal void PowerOffIn(int seconds) { + ClearPowerOffTask(); + _powerOffTimer = new Timer(PowerOffByTimer); _powerOffTimer.Change(TimeSpan.FromSeconds(seconds), TimeSpan.FromSeconds(seconds)); } - private void PowerOffByTimer(object state) + private void PowerOffByTimer(object _) { - _powerOffTimer?.Dispose(); + ClearPowerOffTask(); - var _ = PowerOff(true); + Logger.Debug($"Device {Name} is now powering off due to delayed screensaver task"); + + var x = PowerOff(true, false); + + //Task.Run(async () => + //{ + // // Do not force reconnect here (MessageWebSocket issues) + // await PowerOff(true, false); + //}); } } } diff --git a/ColorControl/Services/LG/LgService.cs b/ColorControl/Services/LG/LgService.cs index 602dd26..edf7706 100644 --- a/ColorControl/Services/LG/LgService.cs +++ b/ColorControl/Services/LG/LgService.cs @@ -9,6 +9,7 @@ using Newtonsoft.Json; using NWin32; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; @@ -88,6 +89,7 @@ namespace ColorControl.Services.LG private int _poweredOffByScreenSaverProcessId; private LgPreset _lastTriggeredPreset; private RestartDetector _restartDetector; + private SynchronizationContext _syncContext; public LgService(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, ProcessEventDispatcher processEventDispatcher) : base(appContextProvider) { @@ -98,6 +100,7 @@ namespace ColorControl.Services.LG LgPreset.LgApps = _lgApps; _restartDetector = new RestartDetector(); + _syncContext = AsyncOperationManager.SynchronizationContext; LoadConfig(); LoadPresets(); @@ -434,6 +437,8 @@ namespace ColorControl.Services.LG internal void WakeAfterStartupOrResume(PowerOnOffState state = PowerOnOffState.StartUp, bool checkUserSession = true) { + Devices.ForEach(d => d.ClearPowerOffTask()); + var wakeDevices = Devices.Where(d => state == PowerOnOffState.StartUp && d.PowerOnAfterStartup || state == PowerOnOffState.Resume && d.PowerOnAfterResume || state == PowerOnOffState.ScreenSaver && d.PowerOnAfterScreenSaver); @@ -456,12 +461,11 @@ namespace ColorControl.Services.LG private void SessionSwitched(object sender, SessionSwitchEventArgs e) { - if (_sessionSwitchDispatcher.UserLocalSession) + if (!_sessionSwitchDispatcher.UserLocalSession) { return; } - if (_poweredOffByScreenSaver) { Logger.Debug("User switched to local and screen was powered off due to screensaver: waking up"); @@ -483,8 +487,6 @@ namespace ColorControl.Services.LG if (powerOn) { - Devices.ForEach(d => d.ClearPowerOffTask()); - WakeAfterStartupOrResume(PowerOnOffState.Resume); return; } @@ -553,7 +555,11 @@ namespace ColorControl.Services.LG Logger.Debug("Screensaver stopped, waking"); _poweredOffByScreenSaver = false; _poweredOffByScreenSaverProcessId = 0; - WakeAfterStartupOrResume(PowerOnOffState.ScreenSaver); + + _syncContext.Send((x) => + { + WakeAfterStartupOrResume(PowerOnOffState.ScreenSaver); + }, null); return; } @@ -698,7 +704,16 @@ namespace ColorControl.Services.LG foreach (var device in powerOffDevices) { Logger.Debug($"Screensaver check: test connection with {device.Name}..."); - var test = await device.TestConnection(); + + var test = false; + + _syncContext.Send((x) => + { + var task = device.TestConnection(); + test = Utils.WaitForTask(task); + }, null); + + //var test = await device.TestConnection(); Logger.Debug("Screensaver check: test connection result: " + test); if (!test) { @@ -707,6 +722,8 @@ namespace ColorControl.Services.LG if (device.ScreenSaverMinimalDuration > 0) { + Logger.Debug($"Screensaver check: powering off tv {device.Name} in {device.ScreenSaverMinimalDuration} seconds because of screensaver"); + _poweredOffByScreenSaver = true; device.PowerOffIn(device.ScreenSaverMinimalDuration); @@ -714,7 +731,6 @@ namespace ColorControl.Services.LG continue; } - Logger.Debug($"Screensaver check: powering off tv {device.Name} because of screensaver"); try { diff --git a/ColorControl/Services/NVIDIA/NvDitherPanel.cs b/ColorControl/Services/NVIDIA/NvDitherPanel.cs index a7a19e4..cd5b007 100644 --- a/ColorControl/Services/NVIDIA/NvDitherPanel.cs +++ b/ColorControl/Services/NVIDIA/NvDitherPanel.cs @@ -6,7 +6,7 @@ using System.Windows.Forms; namespace ColorControl.Services.NVIDIA { - public partial class NvDitherPanel : UserControl + public partial class NvDitherPanel : UserControl, IModulePanel { private NvService _nvService; private bool _updatingDitherSettings; @@ -22,18 +22,32 @@ namespace ColorControl.Services.NVIDIA cbxDitheringMode.Items.AddRange(Utils.GetDescriptions().ToArray()); FillGradient(); - var displays = _nvService.GetDisplayInfos(); + RefreshDisplays(); + + UpdateDitherSettings(); + + _initialized = true; + } + + private void RefreshDisplays() + { + var displays = _nvService.GetSimpleDisplayInfos(); + + if (displays == null) + { + return; + } + var primaryDisplay = _nvService.GetPrimaryDisplay(); var primaryDisplayInfo = displays.FirstOrDefault(d => d.Display == primaryDisplay); var index = primaryDisplayInfo != null ? displays.IndexOf(primaryDisplayInfo) : 0; cbxDitheringDisplay.Items.AddRange(displays.ToArray()); - cbxDitheringDisplay.SelectedIndex = index; - - UpdateDitherSettings(); - - _initialized = true; + if (cbxDitheringDisplay.SelectedIndex == -1) + { + cbxDitheringDisplay.SelectedIndex = index; + } } private void UpdateDitherSettings() @@ -118,5 +132,11 @@ namespace ColorControl.Services.NVIDIA UpdateDitherSettings(); } + + public void UpdateInfo() + { + RefreshDisplays(); + UpdateDitherSettings(); + } } } diff --git a/ColorControl/Services/NVIDIA/NvService.cs b/ColorControl/Services/NVIDIA/NvService.cs index 3692ce8..6c55b9f 100644 --- a/ColorControl/Services/NVIDIA/NvService.cs +++ b/ColorControl/Services/NVIDIA/NvService.cs @@ -240,8 +240,17 @@ namespace ColorControl.Services.NVIDIA public Display GetPrimaryDisplay() { - var displayId = DisplayDevice.GetGDIPrimaryDisplayDevice().DisplayId; - return Display.GetDisplays().FirstOrDefault(x => x.DisplayDevice.DisplayId == displayId); + try + { + var displayId = DisplayDevice.GetGDIPrimaryDisplayDevice().DisplayId; + return Display.GetDisplays().FirstOrDefault(x => x.DisplayDevice.DisplayId == displayId); + } + catch (Exception ex) + { + Logger.Error(ex, "Error while getting primary display device"); + + return null; + } } public bool ApplyPreset(string idOrName) @@ -679,6 +688,23 @@ namespace ColorControl.Services.NVIDIA return gpus; } + public List GetSimpleDisplayInfos() + { + var displays = GetDisplays(); + var list = new List(); + + foreach (var display in displays) + { + var name = FormUtils.ExtendedDisplayName(display.Name); + + var displayInfo = new NvDisplayInfo(display, null, null, name); + + list.Add(displayInfo); + } + + return list; + } + public List GetDisplayInfos() { try diff --git a/ColorControl/lgtv/LgTvApi.cs b/ColorControl/lgtv/LgTvApi.cs index 7061d55..f2fe6f9 100644 --- a/ColorControl/lgtv/LgTvApi.cs +++ b/ColorControl/lgtv/LgTvApi.cs @@ -288,31 +288,38 @@ namespace LgTv public static async Task CreateLgTvApi(string ip, int retries = 1, bool useSecureWs = true) { - var instance = new LgTvApi(ip, new LgTvApiCore(), new ClientKeyStore(ip), useSecureWs); + var instance = new LgTvApi(ip, useSecureWs); - Logger.Debug($"Trying to connect with websocket uri: {instance.webSocketUri}"); + return await instance.Connect(retries); + } + + private LgTvApi(string ip, bool useSecureWs) + { + webSocketUri = useSecureWs ? $"wss://{ip}:3001" : $"ws://{ip}:3000"; + _ip = ip; + _connection = new LgTvApiCore(); + _keyStore = new ClientKeyStore(ip); + } + + private async Task Connect(int retries) + { + Logger.Debug($"Trying to connect with websocket uri: {webSocketUri}"); while (retries > 0) { - var connected = await instance.Connect(); + var connected = await Connect(); if (connected) { - await instance.MakeHandShake(); - return instance; + await MakeHandShake(); + return this; } retries--; await Task.Delay(500); } - instance.Dispose(); - return null; - } - private LgTvApi(string ip, LgTvApiCore connection, ClientKeyStore keyStore, bool useSecureWs) - { - webSocketUri = useSecureWs ? $"wss://{ip}:3001" : $"ws://{ip}:3000"; - _ip = ip; - _connection = connection; - _keyStore = keyStore; + Dispose(); + + return null; } public string GetIpAddress() diff --git a/ColorControl/lgtv/LgTvConnection.cs b/ColorControl/lgtv/LgTvConnection.cs index f433e7d..64d7d9c 100644 --- a/ColorControl/lgtv/LgTvConnection.cs +++ b/ColorControl/lgtv/LgTvConnection.cs @@ -38,8 +38,11 @@ namespace LgTv { try { + _connection?.Dispose(); + ConnectionClosed = false; _commandCount = 0; + _connection = new MessageWebSocket(); _connection.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted); _connection.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName); diff --git a/NvAPIWrapper/NvAPIWrapper.csproj b/NvAPIWrapper/NvAPIWrapper.csproj index 885e42e..d5822b3 100644 --- a/NvAPIWrapper/NvAPIWrapper.csproj +++ b/NvAPIWrapper/NvAPIWrapper.csproj @@ -2,7 +2,7 @@ net7.0-windows10.0.20348.0 - 0.8.1.102 + 0.8.1.103 falahati.net NvAPIWrapper is a .Net wrapper for NVIDIA public API Soroush Falahati