diff --git a/ArcticControl.GPUInterop/ArcticControl.GPUInterop.cpp b/ArcticControl.GPUInterop/ArcticControl.GPUInterop.cpp index 618c79b..14886e2 100644 --- a/ArcticControl.GPUInterop/ArcticControl.GPUInterop.cpp +++ b/ArcticControl.GPUInterop/ArcticControl.GPUInterop.cpp @@ -1,4 +1,3 @@ -#define _CRTDBG_MAP_ALLOC #include "pch.h" #include @@ -634,6 +633,8 @@ ArcticControlGPUInterop::GPUInterop::!GPUInterop() if (hAPIHandle != nullptr) { ctlClose(*hAPIHandle); + free(hAPIHandle); + hAPIHandle = nullptr; } CTL_FREE_MEM(hDevices); diff --git a/ArcticControl.GPUInterop/pch.h b/ArcticControl.GPUInterop/pch.h index cdc784b..1b4aff1 100644 --- a/ArcticControl.GPUInterop/pch.h +++ b/ArcticControl.GPUInterop/pch.h @@ -7,6 +7,8 @@ #ifndef PCH_H #define PCH_H +#define _CRTDBG_MAP_ALLOC + // Fügen Sie hier Header hinzu, die vorkompiliert werden sollen. #include #include diff --git a/ArcticControl/App.xaml.cs b/ArcticControl/App.xaml.cs index 47be2ad..6d77be6 100644 --- a/ArcticControl/App.xaml.cs +++ b/ArcticControl/App.xaml.cs @@ -1,4 +1,5 @@ -using ArcticControl.Activation; +using System.Diagnostics; +using ArcticControl.Activation; using ArcticControl.Contracts.Services; using ArcticControl.Core.Contracts.Services; using ArcticControl.Core.Services; @@ -98,7 +99,8 @@ public App() services.AddSingleton(); services.AddSingleton(); - // Intel Web Api Service + // Intel Services + services.AddSingleton(); services.AddSingleton(); // Views and ViewModels diff --git a/ArcticControl/Contracts/Services/IIntelGraphicsControlService.cs b/ArcticControl/Contracts/Services/IIntelGraphicsControlService.cs new file mode 100644 index 0000000..f029d01 --- /dev/null +++ b/ArcticControl/Contracts/Services/IIntelGraphicsControlService.cs @@ -0,0 +1,19 @@ +using ArcticControlGPUInterop; + +namespace ArcticControl.Contracts.Services; +public interface IIntelGraphicsControlService : IDisposable +{ + public bool IsInitialized(); + public bool SetOverclockWaiver(); + public double GetOverclockPowerLimit(); + public double GetOverclockTemperatureLimit(); + public double GetOverclockGPUVoltageOffset(); + public double GetOverclockGPUFrequencyOffset(); + public bool SetOverclockPowerLimit(double newPowerLimit); + public bool SetOverclockTemperatureLimit(double newGPUTemperatureLimit); + public bool SetOverclockGPUVoltageOffset(double newGPUVoltageOffset); + public bool SetOverclockGPUFrequencyOffset(double newGPUFrequencyOffset); + public bool InitPowerDomains(); + public PowerProperties? GetPowerProperties(); + public PowerLimitsCombination? GetPowerLimits(); +} diff --git a/ArcticControl/Helpers/InstalledDriverHelper.cs b/ArcticControl/Helpers/InstalledDriverHelper.cs index 466e3cd..b68e77e 100644 --- a/ArcticControl/Helpers/InstalledDriverHelper.cs +++ b/ArcticControl/Helpers/InstalledDriverHelper.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.Management; -using ArcticControlGPUInterop; namespace ArcticControl.Helpers; diff --git a/ArcticControl/MainWindow.xaml b/ArcticControl/MainWindow.xaml index d045203..01e3737 100644 --- a/ArcticControl/MainWindow.xaml +++ b/ArcticControl/MainWindow.xaml @@ -9,6 +9,7 @@ MinWidth="500" MinHeight="500" PersistenceId="MainWindow" + Closed="WindowEx_Closed" mc:Ignorable="d"> diff --git a/ArcticControl/MainWindow.xaml.cs b/ArcticControl/MainWindow.xaml.cs index e81ef47..756f9e2 100644 --- a/ArcticControl/MainWindow.xaml.cs +++ b/ArcticControl/MainWindow.xaml.cs @@ -1,4 +1,6 @@ -using ArcticControl.Helpers; +using System.Diagnostics; +using ArcticControl.Contracts.Services; +using ArcticControl.Helpers; namespace ArcticControl; @@ -17,4 +19,10 @@ public MainWindow() manager.MinWidth = 1200; manager.MaxWidth = 1600; } + + private void WindowEx_Closed(object sender, Microsoft.UI.Xaml.WindowEventArgs args) + { + // TODO: direct invoke of dispose() method ; change if WindowsAppSDK calls disposables + App.GetService().Dispose(); + } } diff --git a/ArcticControl/Services/AppNotificationService.cs b/ArcticControl/Services/AppNotificationService.cs index f9846f4..4502fad 100644 --- a/ArcticControl/Services/AppNotificationService.cs +++ b/ArcticControl/Services/AppNotificationService.cs @@ -79,7 +79,6 @@ public bool ShowMessage(string message) public bool ShowWithActionAndProgressBar(string payload, string filePath, string status, string title, double pbValue, string valueStringOverride) { var appNotification = new AppNotificationBuilder() - .AddButton(new AppNotificationButton("Install (under dev)").SetInvokeUri(new Uri(string.Concat("file://", filePath)))) .AddButton(new AppNotificationButton("Open in explorer").SetInvokeUri(new Uri(string.Concat("file://", filePath.AsSpan(0, filePath.LastIndexOf("/")))))) .AddText(payload) .AddProgressBar(new AppNotificationProgressBar() diff --git a/ArcticControl/Services/IntelGraphicsControlService.cs b/ArcticControl/Services/IntelGraphicsControlService.cs index daa291e..dfe9cba 100644 --- a/ArcticControl/Services/IntelGraphicsControlService.cs +++ b/ArcticControl/Services/IntelGraphicsControlService.cs @@ -1,18 +1,294 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics; +using ArcticControl.Contracts.Services; +using ArcticControlGPUInterop; +using Microsoft.AppCenter.Crashes; namespace ArcticControl.Services; -internal class IntelGraphicsControlService +public class IntelGraphicsControlService: IIntelGraphicsControlService, IDisposable { - public static void MyFunc() + private readonly bool _initialized; + private readonly GPUInterop _gpuInterop; + + public IntelGraphicsControlService() + { + _gpuInterop = new(); + _initialized = _gpuInterop.InitCtlApi(); + } + + public bool IsInitialized() => _initialized; + + public bool SetOverclockWaiver() + { + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.SetOverclockWaiver(); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - SetOverclockWaiver"); + Crashes.TrackError(ex); + } + + return false; + } + + public double GetOverclockPowerLimit() + { + if (!_initialized) + { + return 0.0; + } + + try + { + var powerLimit = _gpuInterop.GetOverclockPowerLimit(); + if (powerLimit != null) + { + return (double)powerLimit; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetOverclockPowerLimit"); + Crashes.TrackError(ex); + } + + return 0.0; + } + + public double GetOverclockTemperatureLimit() + { + if (!_initialized) + { + return 0.0; + } + + try + { + var overclockTempLimit = _gpuInterop.GetOverclockTemperatureLimit(); + if (overclockTempLimit != null) + { + return (double)overclockTempLimit; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetOverclockTemperatureLimit"); + Crashes.TrackError(ex); + } + + return 0.0; + } + + public double GetOverclockGPUVoltageOffset() + { + if (!_initialized) + { + return 0.0; + } + + try + { + var gpuVoltageOffset = _gpuInterop.GetOverclockGPUVoltageOffset(); + if (gpuVoltageOffset != null) + { + return (double)gpuVoltageOffset; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetOverclockGPUVoltageOffset"); + Crashes.TrackError(ex); + } + + return 0.0; + } + + public double GetOverclockGPUFrequencyOffset() + { + if (!_initialized) + { + return 0.0; + } + + try + { + var gpuFrequencyOffset = _gpuInterop.GetOverclockGPUFrequencyOffset(); + if (gpuFrequencyOffset != null) + { + return (double)gpuFrequencyOffset; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetOverclockGPUFrequencyOffset"); + Crashes.TrackError(ex); + } + + return 0.0; + } + + public bool SetOverclockPowerLimit(double newPowerLimit) { - //ArcticControl_IGCLInteop.Class c = new ArcticControl.ig.Class(); - //c.MyProperty= 1; - //Console.WriteLine(c.MyProperty); - //Class1 cl1 = new Class1(); - //cl1.main(); + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.SetOverclockPowerLimit(newPowerLimit); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - SetOverclockPowerLimit"); + Crashes.TrackError(ex); + } + + return false; } + + public bool SetOverclockTemperatureLimit(double newGPUTemperatureLimit) + { + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.SetOverclockTemperatureLimit(newGPUTemperatureLimit); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - SetOverclockTemperatureLimit"); + Crashes.TrackError(ex); + } + + return false; + } + + public bool SetOverclockGPUVoltageOffset(double newGPUVoltageOffset) + { + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.SetOverclockGPUVoltageOffset(newGPUVoltageOffset); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - SetOverclockGPUVoltageOffset"); + Crashes.TrackError(ex); + } + + return false; + } + + public bool SetOverclockGPUFrequencyOffset(double newGPUFrequencyOffset) + { + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.SetOverclockGPUVoltageOffset(newGPUFrequencyOffset); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - SetOverclockGPUFrequencyOffset"); + Crashes.TrackError(ex); + } + + return false; + } + + public bool InitPowerDomains() + { + if (!_initialized) + { + return false; + } + + try + { + var result = _gpuInterop.InitPowerDomains(); + return result; + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - InitPowerDomains"); + Crashes.TrackError(ex); + } + + return default; + } + + public PowerProperties? GetPowerProperties() + { + if (!_initialized) + { + return null; + } + + try + { + PowerProperties? result = _gpuInterop.GetPowerProperties(); + if (result != null) + { + return result; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetPowerProperties"); + Crashes.TrackError(ex); + } + + return default; + } + + public PowerLimitsCombination? GetPowerLimits() + { + if (!_initialized) + { + return null; + } + + try + { + PowerLimitsCombination? result = _gpuInterop.GetPowerLimits(); + if (result != null) + { + return result; + } + } + catch (Exception ex) + { + Debug.WriteLine("[IntelGraphicsControlService]: Error - GetPowerLimits"); + Crashes.TrackError(ex); + } + + return default; + } + + /// + /// DON'T CALL THIS METHOD MANUALLY. + /// + public void Dispose() => _gpuInterop.Dispose(); } diff --git a/ArcticControl/Strings/en-us/Resources.resw b/ArcticControl/Strings/en-us/Resources.resw index f5a0091..f59cc41 100644 --- a/ArcticControl/Strings/en-us/Resources.resw +++ b/ArcticControl/Strings/en-us/Resources.resw @@ -231,7 +231,7 @@ Advanced (be aware these settings can damage your hardware, this is on your own risk) - GPU maximal Power Limit (does not work on any hardware for values over 228W) + GPU maximal Power Limit (does not work on any hardware) Your input is invalid. It must be greater that 228 and smaller than 400. diff --git a/ArcticControl/ViewModels/PerformanceViewModel.cs b/ArcticControl/ViewModels/PerformanceViewModel.cs index 6d72311..83f2409 100644 --- a/ArcticControl/ViewModels/PerformanceViewModel.cs +++ b/ArcticControl/ViewModels/PerformanceViewModel.cs @@ -31,7 +31,7 @@ internal static class SliderDefaultValues internal const ushort FanSpeed = 20; } -public class PerformanceViewModel : ObservableRecipient, INavigationAware, IDisposable +public class PerformanceViewModel : ObservableRecipient, INavigationAware { /// /// INOP at the moment cause no NotifyCollectionChangedAction available for indicating changes in an element. @@ -134,16 +134,20 @@ public PerformanceValueDataObject GPUVolatageObj } #endregion - public PerformanceViewModel(ILocalSettingsService localSettingsService) + public PerformanceViewModel( + ILocalSettingsService localSettingsService, + IIntelGraphicsControlService intelGraphicsControlService) { _localSettingsService = localSettingsService; - _gpuInterop = new GPUInterop(); + // _gpuInterop = new GPUInterop(); + _igcs = intelGraphicsControlService; } private DispatcherQueue? _dpq; private CancellationTokenSource? _tickTimerTaskCancelationTokenSource; private Task? _tickTimerTask; - private readonly GPUInterop _gpuInterop; + //private readonly GPUInterop _gpuInterop; + private readonly IIntelGraphicsControlService _igcs; private readonly ILocalSettingsService _localSettingsService; // framecounter, UI Binded Property, format, @@ -287,25 +291,25 @@ public async void OnNavigatedTo(object parameter) Debug.WriteLine(res); }*/ - var result = (bool)_gpuInterop.InitCtlApi(); - if (result) + //var result = (bool)_gpuInterop.InitCtlApi(); + if (_igcs.IsInitialized()) { GetOverclockingValues(); // TODO: move somewhere // GPUPowerTest -#if DEBUG - result = _gpuInterop.InitPowerDomains(); + + var result = _igcs.InitPowerDomains(); if (result) { Debug.WriteLine("PowerInit: Res true"); - var powerProps = _gpuInterop.GetPowerProperties(); + var powerProps = _igcs.GetPowerProperties(); if (powerProps != null) { Debug.WriteLine( $"PowerProps: CanControl-{powerProps.CanControl} ; DefaultLimit-{powerProps.DefaultLimit} ;" + $" MinLimit-{powerProps.MinLimit} ; MaxLimit-{powerProps.MaxLimit}"); } - var powerLimits = _gpuInterop.GetPowerLimits(); + var powerLimits = _igcs.GetPowerLimits(); if (powerLimits != null) { Debug.WriteLine($"PowerLimits: " + Environment.NewLine + @@ -314,7 +318,6 @@ public async void OnNavigatedTo(object parameter) $"PeakPowerLimit: PowerDC-{powerLimits.PeakPowerLimit.PowerDC} ; PowerAC-{powerLimits.PeakPowerLimit.PowerAC}"); } } -#endif } var settingsGPUPowerMaxLimit = await _localSettingsService.ReadSettingAsync(LocalSettingsKeys.GPUPowerMaxLimit); @@ -323,12 +326,12 @@ public async void OnNavigatedTo(object parameter) private void GetOverclockingValues(bool skipTempLimit = false) { - var powerLimit = (double)_gpuInterop.GetOverclockPowerLimit(); + var powerLimit = _igcs.GetOverclockPowerLimit(); var tempLimit = skipTempLimit ? GPUTemperatureLimitSliderValue - : (double)_gpuInterop.GetOverclockTemperatureLimit(); - var gpuVoltageOffset = (double)_gpuInterop.GetOverclockGPUVoltageOffset(); - var gpuFrequencyOffset = (double)_gpuInterop.GetOverclockGPUFrequencyOffset(); + : _igcs.GetOverclockTemperatureLimit(); + var gpuVoltageOffset = _igcs.GetOverclockGPUVoltageOffset(); + var gpuFrequencyOffset = _igcs.GetOverclockGPUFrequencyOffset(); GPUPowerLimitSliderValue = powerLimit; GPUTemperatureLimitSliderValue = tempLimit; @@ -367,7 +370,7 @@ public bool ApplyChanges() if (GPUPowerLimitSliderValue != CurrentActiveSliderValues[SliderValueDefaults.GPUPowerLimit]) { // *1000 to convert W in mW - _gpuInterop.SetOverclockPowerLimit(GPUPowerLimitSliderValue*1000.0); + _igcs.SetOverclockPowerLimit(GPUPowerLimitSliderValue*1000.0); } if (GPUTemperatureLimitSliderValue != CurrentActiveSliderValues[SliderValueDefaults.GPUTemperatureLimit]) { @@ -375,7 +378,7 @@ public bool ApplyChanges() { return false; } - var result = (bool)_gpuInterop.SetOverclockTemperatureLimit(GPUTemperatureLimitSliderValue); + var result = _igcs.SetOverclockTemperatureLimit(GPUTemperatureLimitSliderValue); if (result) { // skip temp limit check because the gpu needs time to refresh values so it would return old tempLimit @@ -388,7 +391,7 @@ public bool ApplyChanges() { return false; } - _gpuInterop.SetOverclockGPUVoltageOffset(GPUVoltageOffsetSliderValue); + _igcs.SetOverclockGPUVoltageOffset(GPUVoltageOffsetSliderValue); } if (GPUFrequencyOffsetSliderValue != CurrentActiveSliderValues[SliderValueDefaults.GPUFrequencyOffset]) { @@ -396,7 +399,7 @@ public bool ApplyChanges() { return false; } - _gpuInterop.SetOverclockGPUFrequencyOffset(GPUFrequencyOffsetSliderValue); + _igcs.SetOverclockGPUFrequencyOffset(GPUFrequencyOffsetSliderValue); } // check if gpu driver acepted values or adjust some and also reset CurrentValues variable @@ -407,7 +410,7 @@ public bool ApplyChanges() public void SetOverclockWaiver() { - _gpuInterop.SetOverclockWaiver(); + _igcs.SetOverclockWaiver(); } public async void OnNavigatedFrom() @@ -430,6 +433,4 @@ public async void OnNavigatedFrom() } } } - - public void Dispose() => _gpuInterop.Dispose(); } diff --git a/ArcticControl/Views/DriversDetailControl.xaml b/ArcticControl/Views/DriversDetailControl.xaml index 22a992f..69770d3 100644 --- a/ArcticControl/Views/DriversDetailControl.xaml +++ b/ArcticControl/Views/DriversDetailControl.xaml @@ -63,17 +63,18 @@ - - + + + + x:Name="DownloadProgressBar" + Margin="{StaticResource SmallTopMargin}" + HorizontalAlignment="Stretch" + IsIndeterminate="True" + ShowPaused="False" + ShowError="False" + Visibility="Collapsed"/> diff --git a/ArcticControl/Views/DriversDetailControl.xaml.cs b/ArcticControl/Views/DriversDetailControl.xaml.cs index 54ae025..f659e88 100644 --- a/ArcticControl/Views/DriversDetailControl.xaml.cs +++ b/ArcticControl/Views/DriversDetailControl.xaml.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.IO.Compression; using ArcticControl.Contracts.Services; using ArcticControl.Helpers; using ArcticControl.IntelWebAPI.Models; @@ -81,19 +82,32 @@ private static void OnListDetailsMenuItemPropertyChanged(DependencyObject d, Dep private async void DownloadDriverButton_Click(object sender, RoutedEventArgs e) { // TODO: move code into singleton service to don't interrupt on page change but sync with button progressbar or notification from service + try { using var client = _httpClientFactory.CreateClient(); DownloadProgressBar.Visibility = Visibility.Visible; - var downloadStream = await client.GetStreamAsync(ListDetailsMenuItem?.DownloadUri); + using var downloadStream = await client.GetStreamAsync(ListDetailsMenuItem?.DownloadUri); var localFile = await DownloadsFolder.CreateFileAsync( - ListDetailsMenuItem?.DownloadUri?.Segments.Last()); + ListDetailsMenuItem?.DownloadUri?.Segments.Last()+".zip"); // write - using var fsStream = await localFile.OpenStreamForWriteAsync(); - await downloadStream.CopyToAsync(fsStream); + //using var fsStream = await localFile.OpenStreamForWriteAsync(); + //await downloadStream.CopyToAsync(fsStream); + + // workaround for microsoft store + using (var fsStream = await localFile.OpenStreamForWriteAsync()) + { + fsStream.Seek(0, SeekOrigin.Begin); + + using var archive = new ZipArchive(fsStream, ZipArchiveMode.Create, false); + var installerFile = archive.CreateEntry(ListDetailsMenuItem?.DownloadUri?.Segments.Last() ?? "Installer.exe"); + + using var entryStream = installerFile.Open(); + await downloadStream.CopyToAsync(entryStream); + } DownloadProgressBar.Visibility = Visibility.Collapsed; diff --git a/ArcticControl/Views/PerformancePage.xaml.cs b/ArcticControl/Views/PerformancePage.xaml.cs index cc85a59..2e6f4c7 100644 --- a/ArcticControl/Views/PerformancePage.xaml.cs +++ b/ArcticControl/Views/PerformancePage.xaml.cs @@ -1,4 +1,5 @@ -using ArcticControl.ViewModels; +using System.Diagnostics; +using ArcticControl.ViewModels; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -86,7 +87,7 @@ private async Task CheckWaiver() ContentDialog dialog = new() { - Content = "The tuning of your GPU can cause instability or damage your components. You do all on your own risk. The author of this application does not take responsibility for any damage to your hardware. (It is required that you run this application as administrator if you want the settings to take effect!)", + Content = "The tuning of your GPU can cause instability or damage your components. You do all changes to these settings on your own risk. The author of this application does not take responsibility for any damage to your hardware. (It is required that you run this application as administrator if you want the settings to take effect!)", PrimaryButtonText = "Acept & Continue", CloseButtonText = "Cancel" }; @@ -178,13 +179,13 @@ private async void FanSpeedSlider_ValueChanged(object sender, RangeBaseValueChan await CheckWaiver(); } - private void GridView_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) + private async void GridView_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { // The await causes the handler to return immediately. //Task.Run(() => StartBackgroundTickTimer()); // Now update the UI with the results. // ... - ViewModel.StartBackgroundTickTimer(DispatcherQueue.GetForCurrentThread()); + await Task.Run(() => ViewModel.StartBackgroundTickTimer(DispatcherQueue.GetForCurrentThread())); _waiverEnabled = true; }