diff --git a/TimVer/Helpers/VideoHelpers.cs b/TimVer/Helpers/VideoHelpers.cs index f1d278d..0c677dc 100644 --- a/TimVer/Helpers/VideoHelpers.cs +++ b/TimVer/Helpers/VideoHelpers.cs @@ -7,54 +7,32 @@ namespace TimVer.Helpers; /// internal static class VideoHelpers { - #region Get list of video controllers + #region Get all video controllers with full info /// - /// Gets the DeviceID for each video controller. + /// Gets all video controllers with their complete information. /// - /// A List of controller DeviceID's - internal static List GetGPUList() + /// A list of dictionaries containing video controller information + internal static List> GetAllVideoControllers() { const string scope = @"\\.\root\CIMV2"; const string dialect = "WQL"; - const string query = "SELECT DeviceID From Win32_VideoController"; - - try - { - List devices = []; - using CimSession cimSession = CimSession.Create(null); - devices.AddRange(cimSession.QueryInstances(scope, dialect, query) - .Select(drive => drive.CimInstanceProperties["DeviceID"]?.Value!.ToString())); - return devices; - } - catch (Exception ex) - { - _log.Error(ex, "Win32_VideoController call failed."); - return []; - } - } - #endregion Get list of video controllers - - #region Get WMI info for video controller(s) - /// - /// Get CIM value from Win32_VideoController - /// - /// DeviceID of the controller - /// Video controller information as a Dictionary - public static Dictionary GetVideoInfo(string controller) - { - const string scope = @"\\.\root\CIMV2"; - const string dialect = "WQL"; - string query = "SELECT DeviceID, Name, Description, CurrentHorizontalResolution, CurrentVerticalResolution, " + - "CurrentRefreshRate, CurrentBitsPerPixel, VideoProcessor, " + - "AdapterRam, CurrentNumberOfColors " + - $"From Win32_VideoController Where DeviceID = '{controller}'"; + const string query = "SELECT DeviceID, Name, Description, CurrentHorizontalResolution, CurrentVerticalResolution, " + + "CurrentRefreshRate, CurrentBitsPerPixel, VideoProcessor, " + + "AdapterRam, CurrentNumberOfColors " + + "FROM Win32_VideoController"; try { + List> controllers = []; using CimSession cimSession = CimSession.Create(null); - IEnumerable instance = cimSession.QueryInstances(scope, dialect, query); Stopwatch sw = Stopwatch.StartNew(); - Dictionary info = instance - .Select(gpu => new Dictionary + + var instances = cimSession.QueryInstances(scope, dialect, query); + + int displayCount = GetDisplayCount(); + + foreach (var gpu in instances) + { + Dictionary controllerInfo = new() { [GetStringResource("GraphicsInfo_GraphicsAdapter")] = CimStringProperty(gpu, "Name"), [GetStringResource("GraphicsInfo_AdapterType")] = CimStringProperty(gpu, "VideoProcessor"), @@ -62,30 +40,27 @@ public static Dictionary GetVideoInfo(string controller) [GetStringResource("GraphicsInfo_DeviceID")] = CimStringProperty(gpu, "DeviceID"), [GetStringResource("GraphicsInfo_CurrentResolution")] = FormatResolution(gpu), [GetStringResource("GraphicsInfo_CurrentRefreshRate")] = FormatCurrentRefresh(gpu), - //[GetStringResource("GraphicsInfo_AdapterRAM")] = FormatAdapterRamInfo(gpu), + [GetStringResource("GraphicsInfo_AdapterRAM")] = FormatAdapterRamInfo(gpu), [GetStringResource("GraphicsInfo_BitsPerPixel")] = CimStringProperty(gpu, "CurrentBitsPerPixel"), [GetStringResource("GraphicsInfo_NumberOfColors")] = FormatColorsInfo(gpu), - [GetStringResource("GraphicsInfo_NumberOfDisplays")] = GetDisplayCount() - .ToString(CultureInfo.InvariantCulture), - }) - .FirstOrDefault()!; + [GetStringResource("GraphicsInfo_NumberOfDisplays")] = displayCount.ToString(CultureInfo.InvariantCulture), + }; + controllers.Add(controllerInfo); + _log.Debug($"Found video controller: {controllerInfo[GetStringResource("GraphicsInfo_GraphicsAdapter")]} (Device ID is " + + $"{controllerInfo[GetStringResource("GraphicsInfo_DeviceID")]})"); + } + sw.Stop(); - _log.Debug($"Getting video controller info took {sw.Elapsed.TotalMilliseconds:N2} ms"); - return info ?? new Dictionary - { - [GetStringResource("MsgText_NotAvailable")] = string.Empty - }; + _log.Debug($"Getting all video controller info took {sw.Elapsed.TotalMilliseconds:N2} ms. Found {controllers.Count} controller(s)"); + return controllers; } catch (Exception ex) { - _log.Error(ex, "Win32_VideoController call failed."); - return new Dictionary - { - [GetStringResource("MsgText_NotAvailable")] = string.Empty - }; + _log.Error(ex, $"Win32_VideoController call failed. {ex.Message} - {ex.InnerException}"); + return []; } } - #endregion Get WMI info for video controller(s) + #endregion Get all video controllers with full info #region Get WMI information formatted as string /// @@ -99,7 +74,12 @@ private static string CimStringProperty(CimInstance instance, string name) if (instance.CimInstanceProperties[name] == null) { _log.Debug($"Value for {name} was null"); - return "Not Available"; + return GetStringResource("MsgText_NotAvailable"); + } + if (instance.CimInstanceProperties[name].Value == null) + { + _log.Debug($"Value for {name} was null"); + return GetStringResource("MsgText_NotAvailable"); } return instance.CimInstanceProperties[name].Value.ToString()!; } @@ -113,8 +93,13 @@ private static string CimStringProperty(CimInstance instance, string name) /// A formatted string. private static string FormatCurrentRefresh(CimInstance instance) { - string? rate = instance.CimInstanceProperties["CurrentRefreshRate"].Value.ToString(); - return $"{rate} Hz"; + var rateValue = instance.CimInstanceProperties["CurrentRefreshRate"]?.Value; + if (rateValue == null) + { + _log.Debug("CurrentRefreshRate was null"); + return GetStringResource("MsgText_NotAvailable"); + } + return $"{rateValue} Hz"; } #endregion Get current refresh rate @@ -126,9 +111,15 @@ private static string FormatCurrentRefresh(CimInstance instance) /// A formatted string. private static string FormatResolution(CimInstance instance) { - string? horz = instance.CimInstanceProperties["CurrentHorizontalResolution"].Value.ToString(); - string? vert = instance.CimInstanceProperties["CurrentVerticalResolution"].Value.ToString(); - return $"{horz} x {vert}"; + object? horzValue = instance.CimInstanceProperties["CurrentHorizontalResolution"]?.Value; + object? vertValue = instance.CimInstanceProperties["CurrentVerticalResolution"]?.Value; + + if (horzValue == null || vertValue == null) + { + _log.Debug("Resolution properties were null"); + return GetStringResource("MsgText_NotAvailable"); + } + return $"{horzValue} x {vertValue}"; } #endregion Get current resolution @@ -139,14 +130,14 @@ private static string FormatResolution(CimInstance instance) /// The CimInstance /// A formatted string. #pragma warning disable RCS1213 // Remove unused member declaration - // Leaving this method in place for now as I may add it back in the future. It is currently commented out in the GetVideoInfo method. + // Leaving this method in place for now as I may add it back in the future. It is currently commented out in the GetAllVideoControllers method. private static string FormatAdapterRamInfo(CimInstance instance) #pragma warning restore RCS1213 // Remove unused member declaration { if (instance.CimInstanceProperties["AdapterRam"] == null) { _log.Debug("Value for AdapterRam was null"); - return "Not Available"; + return GetStringResource("MsgText_NotAvailable"); } double ram = Convert.ToDouble(instance.CimInstanceProperties["AdapterRam"].Value, CultureInfo.InvariantCulture); if (ram >= Math.Pow(1024, 3)) @@ -188,7 +179,7 @@ private static int GetDisplayCount() /// Gets to number of colors. /// /// The CimInstance - /// A formatted string. + /// A string formatted for the current culture. private static string FormatColorsInfo(CimInstance instance) { if (instance.CimInstanceProperties["CurrentNumberOfColors"] == null) @@ -197,21 +188,8 @@ private static string FormatColorsInfo(CimInstance instance) return GetStringResource("MsgText_NotAvailable"); } - ulong colors = Convert.ToUInt64(instance.CimInstanceProperties["CurrentNumberOfColors"].Value, CultureInfo.InvariantCulture); - if (colors >= (ulong)Math.Pow(1024, 2)) - { - colors /= (ulong)Math.Pow(1024, 3); - return string.Format(CultureInfo.CurrentCulture, $"{colors:N2} {GetStringResource("MsgText_Million")}"); - } - else if (colors >= (ulong)Math.Pow(1024, 1)) - { - colors /= (ulong)Math.Pow(1024, 2); - return string.Format(CultureInfo.CurrentCulture, $"{colors:N2} {GetStringResource("MsgText_Thousand")}"); - } - else - { - return string.Format(CultureInfo.CurrentCulture, $"{colors:N0}"); - } + ulong colors = Convert.ToUInt64(instance.CimInstanceProperties["CurrentNumberOfColors"].Value, CultureInfo.CurrentCulture); + return $"{colors:N0}"; } #endregion Total Colors } diff --git a/TimVer/Languages/Strings.en-US.xaml b/TimVer/Languages/Strings.en-US.xaml index 45f71a5..c68a28d 100644 --- a/TimVer/Languages/Strings.en-US.xaml +++ b/TimVer/Languages/Strings.en-US.xaml @@ -152,6 +152,7 @@ Select Adapter If there is more than one video adapter installed use the drop-down to select the adapter to display. + Unknown BIOS BIOS Manufacturer @@ -534,4 +535,8 @@ + + + + \ No newline at end of file diff --git a/TimVer/TimVer.csproj b/TimVer/TimVer.csproj index 7f44c58..f0276ea 100644 --- a/TimVer/TimVer.csproj +++ b/TimVer/TimVer.csproj @@ -26,8 +26,8 @@ true - 0.14.0 - + 0.14.1 + Beta diff --git a/TimVer/ViewModels/VideoViewModel.cs b/TimVer/ViewModels/VideoViewModel.cs index a0b0498..6fe4cc3 100644 --- a/TimVer/ViewModels/VideoViewModel.cs +++ b/TimVer/ViewModels/VideoViewModel.cs @@ -7,7 +7,7 @@ internal sealed partial class VideoViewModel : ObservableObject #region Constructor public VideoViewModel() { - if (VideoInfoCollection == null) + if (AllControllers == null || AllControllers.Count == 0) { LoadData(); } @@ -17,8 +17,10 @@ public VideoViewModel() #region Load data for video properties private static void LoadData() { - ControllerList = VideoHelpers.GetGPUList()!; - VideoInfoCollection = VideoHelpers.GetVideoInfo(ControllerList[0]); + AllControllers = VideoHelpers.GetAllVideoControllers(); + ControllerList = [.. AllControllers.Select(c => + c.GetValueOrDefault( GetStringResource("GraphicsInfo_GraphicsAdapter"), GetStringResource("GraphicsInfo_Unknown")))]; + VideoInfoCollection = AllControllers.FirstOrDefault(); } #endregion Load data for video properties @@ -30,15 +32,18 @@ private static void LoadData() [RelayCommand] private static void SelectVideoController(SelectionChangedEventArgs e) { - if (e.Source is ComboBox box) + if (e.Source is ComboBox box && AllControllers?.Count > 0 + && box.SelectedIndex >= 0 && box.SelectedIndex < AllControllers.Count) { - VideoInfoCollection = VideoHelpers.GetVideoInfo(ControllerList![box.SelectedIndex]); + VideoInfoCollection = AllControllers[box.SelectedIndex]; VideoPage.Instance!.VideoGrid.ItemsSource = VideoInfoCollection; } } #endregion Relay command #region Collections + private static List>? AllControllers { get; set; } + public static List? ControllerList { get; private set; } public static Dictionary? VideoInfoCollection { get; private set; } diff --git a/TimVer/Views/VideoPage.xaml b/TimVer/Views/VideoPage.xaml index 0dc9b19..1e421cc 100644 --- a/TimVer/Views/VideoPage.xaml +++ b/TimVer/Views/VideoPage.xaml @@ -63,9 +63,9 @@ - -