diff --git a/DisplayMagician/GameLibraries/SteamGame.cs b/DisplayMagician/GameLibraries/SteamGame.cs index ff1ae53..7318341 100644 --- a/DisplayMagician/GameLibraries/SteamGame.cs +++ b/DisplayMagician/GameLibraries/SteamGame.cs @@ -85,7 +85,9 @@ namespace DisplayMagician.GameLibraries { try { - if (gameProcess.MainModule.FileName.StartsWith(_steamGameExePath)) + //if (gameProcess.MainModule.FileName.StartsWith(_steamGameExePath)) + // numGameProcesses++; + if (gameProcess.ProcessName.Equals(_steamGameProcessName)) numGameProcesses++; } catch (Exception ex) @@ -98,7 +100,9 @@ namespace DisplayMagician.GameLibraries if (filePath == null) { // if we hit this bit then GameUtils.GetMainModuleFilepath failed, - // so we just skip that process + // so we just assume that the process is a game process + // as it matched the original process search + numGameProcesses++; continue; } else @@ -121,32 +125,32 @@ namespace DisplayMagician.GameLibraries { try { - using ( - var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree)) + using (var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree)) { - if ((int)key?.GetValue(@"Updating", 0) == 1) + if (key != null) { - return true; - } - return false; + int updateValue; + int.TryParse(key.GetValue(@"Updating", 0).ToString(),out updateValue); + if (updateValue == 1) + { + return true; + } + } } } catch (SecurityException ex) { - Console.WriteLine($"SteamGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, $"SteamGame/IsUpdating: SecurityException when trying to open {_gameRegistryKey} registry key"); } catch (IOException ex) { - // Extract some information from this exception, and then - // throw it to the parent method. - Console.WriteLine($"SteamGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, $"SteamGame/IsUpdating: IOException when trying to open {_gameRegistryKey} registry key"); } + catch (Exception ex) + { + logger.Warn(ex, $"SteamGame/IsUpdating: Exception when trying to open {_gameRegistryKey} registry key"); + } + return false; } } diff --git a/DisplayMagician/GameLibraries/SteamLibrary.cs b/DisplayMagician/GameLibraries/SteamLibrary.cs index 95aaaa3..a92de88 100644 --- a/DisplayMagician/GameLibraries/SteamLibrary.cs +++ b/DisplayMagician/GameLibraries/SteamLibrary.cs @@ -20,8 +20,8 @@ namespace DisplayMagician.GameLibraries private static string _steamExe; private static string _steamPath; private static string _steamConfigVdfFile; - private static string _registrySteamKey = @"SOFTWARE\\Valve\\Steam"; - private static string _registryAppsKey = $@"{_registrySteamKey}\\Apps"; + private static string _registrySteamKey = @"SOFTWARE\WOW6432Node\Valve\Steam"; // under LocalMachine + private static string _registryAppsKey = $@"SOFTWARE\Valve\Steam\Apps"; // under CurrentUser private static bool _isSteamInstalled = false; private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); // Other constants that are useful @@ -41,32 +41,40 @@ namespace DisplayMagician.GameLibraries { try { + logger.Trace($"SteamLibrary/SteamLibrary: Steam launcher registry key = HKLM\\{_registrySteamKey}"); // Find the SteamExe location, and the SteamPath for later - using (var key = Registry.CurrentUser.OpenSubKey(SteamLibrary.SteamRegistryKey, RegistryKeyPermissionCheck.ReadSubTree)) + using (var steamInstallKey = Registry.LocalMachine.OpenSubKey(_registrySteamKey, RegistryKeyPermissionCheck.ReadSubTree)) { - _steamExe = (string)key?.GetValue(@"SteamExe", string.Empty) ?? string.Empty; - _steamExe = _steamExe.Replace('/', '\\'); - _steamPath = (string)key?.GetValue(@"SteamPath", string.Empty) ?? string.Empty; - _steamPath = _steamPath.Replace('/', '\\'); - } + if (steamInstallKey == null) + return; + _steamPath = steamInstallKey.GetValue("InstallPath", "C:\\Program Files (x86)\\Steam").ToString(); + _steamExe = $"{_steamPath}\\steam.exe"; + } if (File.Exists(_steamExe)) - _isSteamInstalled = true; + { + logger.Info($"SteamLibrary/SteamLibrary: Steam library is installed in {_steamPath}. Found {_steamExe}"); + _isSteamInstalled = true; + } + else + { + logger.Info($"SteamLibrary/SteamLibrary: Steam library is not installed!"); + } } catch (SecurityException ex) { - logger.Warn(ex,"The user does not have the permissions required to read the Steam registry key."); + logger.Warn(ex, "SteamLibrary/SteamLibrary: The user does not have the permissions required to read the Steam registry key."); } catch (ObjectDisposedException ex) { - logger.Warn(ex, "The Microsoft.Win32.RegistryKey is closed when trying to access theSteam registry key (closed keys cannot be accessed)."); + logger.Warn(ex, "SteamLibrary/SteamLibrary: The Microsoft.Win32.RegistryKey is closed when trying to access the Steam registry key (closed keys cannot be accessed)."); } catch (IOException ex) { - logger.Warn(ex, "The Steam registry key has been marked for deletion so we cannot access the value during the SteamLibrary check."); + logger.Warn(ex, "SteamLibrary/SteamLibrary: The Steam registry key has been marked for deletion so we cannot access the value during the SteamLibrary check."); } catch (UnauthorizedAccessException ex) { - logger.Warn(ex, "The user does not have the necessary registry rights to check whether Steam is installed."); + logger.Warn(ex, "SteamLibrary/SteamLibrary: The user does not have the necessary registry rights to check whether Steam is installed."); } } #endregion @@ -146,12 +154,14 @@ namespace DisplayMagician.GameLibraries // Because then we just update the one that already exists if (ContainsSteamGame(steamGame)) { + logger.Debug($"SteamLibrary/AddSteamGame: Updating Steam game {steamGame.Name} in our Steam library"); // We update the existing Shortcut with the data over SteamGame steamGameToUpdate = GetSteamGame(steamGame.Id.ToString()); steamGame.CopyInto(steamGameToUpdate); } else { + logger.Debug($"SteamLibrary/AddSteamGame: Adding Steam game {steamGame.Name} to our Steam library"); // Add the steamGame to the list of steamGames _allSteamGames.Add(steamGame); } @@ -171,15 +181,21 @@ namespace DisplayMagician.GameLibraries if (!(steamGame is SteamGame)) return false; + logger.Debug($"SteamLibrary/RemoveSteamGame: Removing Steam game {steamGame.Name} from our Steam library"); + // Remove the steamGame from the list. int numRemoved = _allSteamGames.RemoveAll(item => item.Id.Equals(steamGame.Id)); if (numRemoved == 1) { + logger.Debug($"SteamLibrary/RemoveSteamGame: Removed Steam game with name {steamGame.Name}"); return true; } else if (numRemoved == 0) + { + logger.Debug($"SteamLibrary/RemoveSteamGame: Didn't remove Steam game with ID {steamGame.Name} from the Steam Library"); return false; + } else throw new SteamLibraryException(); } @@ -189,15 +205,21 @@ namespace DisplayMagician.GameLibraries if (steamGameId.Equals("0")) return false; + logger.Debug($"SteamLibrary/RemoveSteamGame2: Removing Steam game with ID {steamGameId} from the Steam library"); + // Remove the steamGame from the list. int numRemoved = _allSteamGames.RemoveAll(item => item.Id.Equals(steamGameId)); if (numRemoved == 1) { + logger.Debug($"SteamLibrary/RemoveSteamGame2: Removed Steam game with ID {steamGameId}"); return true; } else if (numRemoved == 0) + { + logger.Debug($"SteamLibrary/RemoveSteamGame2: Didn't remove Steam game with ID {steamGameId} from the Steam Library"); return false; + } else throw new SteamLibraryException(); } @@ -208,6 +230,8 @@ namespace DisplayMagician.GameLibraries if (String.IsNullOrWhiteSpace(steamGameNameOrId)) return false; + logger.Debug($"SteamLibrary/RemoveSteamGame3: Removing Steam game with Name or UUID {steamGameNameOrUuid} from the Steam library"); + int numRemoved; Match match = Regex.Match(steamGameNameOrId, steamAppIdRegex, RegexOptions.IgnoreCase); if (match.Success) @@ -216,9 +240,15 @@ namespace DisplayMagician.GameLibraries numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrId.Equals(item.Name)); if (numRemoved == 1) + { + logger.Debug($"SteamLibrary/RemoveSteamGame3: Removed Steam game with Name or UUID {steamGameNameOrUuid} "); return true; + } else if (numRemoved == 0) + { + logger.Debug($"SteamLibrary/RemoveSteamGame3: Didn't remove Steam game with Name or UUID {steamGameNameOrUuid} from the Steam Library"); return false; + } else throw new SteamLibraryException(); @@ -328,26 +358,15 @@ namespace DisplayMagician.GameLibraries try { - // Find the SteamExe location, and the SteamPath for later - /*using (var key = Registry.CurrentUser.OpenSubKey(_registrySteamKey, RegistryKeyPermissionCheck.ReadSubTree)) - { - _steamExe = (string)key?.GetValue(@"SteamExe", string.Empty) ?? string.Empty; - _steamExe = _steamExe.Replace('/', '\\'); - _steamPath = (string)key?.GetValue(@"SteamPath", string.Empty) ?? string.Empty; - _steamPath = _steamPath.Replace('/', '\\'); - }*/ - if (!_isSteamInstalled) { // Steam isn't installed, so we return an empty list. + logger.Info($"SteamLibrary/LoadInstalledGames: Steam library is not installed"); return false; } - //Icon _steamIcon = Icon.ExtractAssociatedIcon(_steamExe); - //IconExtractor steamIconExtractor = new IconExtractor(_steamExe); - //Icon _steamIcon = steamIconExtractor.GetIcon(0); - //MultiIcon _steamIcon = new MultiIcon(); - //_steamIcon.Load(_steamExe); + logger.Trace($"SteamLibrary/LoadInstalledGames: Steam Base Registry Key = HKLM\\{_registrySteamKey}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Steam Apps Registry Key = HKCU\\{_registryAppsKey}"); List steamAppIdsInstalled = new List(); // Now look for what games app id's are actually installed on this computer @@ -355,23 +374,48 @@ namespace DisplayMagician.GameLibraries { if (steamAppsKey != null) { + // // Loop through the subKeys as they are the Steam Game IDs - foreach (string steamAppId in steamAppsKey.GetSubKeyNames()) + foreach (string steamGameKeyName in steamAppsKey.GetSubKeyNames()) { - string steamGameKeyFullName = $"{_registryAppsKey}\\{steamAppId}"; - using (RegistryKey steamGameKey = Registry.CurrentUser.OpenSubKey(steamGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree)) + logger.Trace($"SteamLibrary/LoadInstalledGames: Found SteamGameKeyName = {steamGameKeyName}"); + if (int.TryParse(steamGameKeyName, out int steamAppId)) { - // If the Installed Value is set to 1, then the game is installed - // We want to keep track of that for later - if ((int)steamGameKey.GetValue(@"Installed", 0) == 1) + logger.Trace($"SteamLibrary/LoadInstalledGames: SteamGameKeyName is an int, so trying to see if it is an installed app"); + string steamGameKeyFullName = $"{_registryAppsKey}\\{steamGameKeyName}"; + using (RegistryKey steamGameKey = Registry.CurrentUser.OpenSubKey(steamGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree)) { - // Add this Steam App ID to the list we're keeping for later - steamAppIdsInstalled.Add(steamAppId); - } + // If the Installed Value is set to 1, then the game is installed + // We want to keep track of that for later + if ((int)steamGameKey.GetValue(@"Installed", 0) == 1) + { + logger.Trace($"SteamLibrary/LoadInstalledGames: {steamGameKeyFullName} contains an 'Installed' value so is an installed Steam App."); + // Add this Steam App ID to the list we're keeping for later + steamAppIdsInstalled.Add(steamAppId); + } + else + { + logger.Trace($"SteamLibrary/LoadInstalledGames: {steamGameKeyFullName} does not contain an 'Installed' value so can't be a Steam App."); + } } + } } + + if (steamAppIdsInstalled.Count == 0) + { + // There aren't any game ids so return false + logger.Warn($"SteamLibrary/LoadInstalledGames: No Steam games installed in the Steam library"); + return false; + } + + } + else + { + // There isnt any steam registry key + logger.Warn($"SteamLibrary/LoadInstalledGames: Couldn't access the Steam Registry Key {_registrySteamKey}"); + return false; } } @@ -386,7 +430,7 @@ namespace DisplayMagician.GameLibraries var newAppInfo = new AppInfo(); newAppInfo.Read(appInfoVdfFile); - Debug.WriteLine($"{newAppInfo.Apps.Count} apps"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Found {newAppInfo.Apps.Count} apps in the {appInfoVdfFile} VDF file"); // Chec through all the apps we've extracted foreach (var app in newAppInfo.Apps) @@ -405,31 +449,35 @@ namespace DisplayMagician.GameLibraries GameID = detectedAppID, GameExes = new List() }; + string steamAppType = ""; foreach (KVObject data in app.Data) { - //Debug.WriteLine($"App: {app.AppID} - Data.Name: {data.Name}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Found App: {app.AppID} - Data.Name: {data.Name}"); if (data.Name == "common") { foreach (KVObject common in data.Children) { - //Debug.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}"); - if (common.Name == "name") { - Debug.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: name: App: {app.AppID} - Common {common.Name}: {common.Value}"); steamGameAppInfo.GameName = common.Value.ToString(); } else if (common.Name == "clienticon") { - Debug.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: clienticon: App: {app.AppID} - Common {common.Name}: {common.Value}"); steamGameAppInfo.GameSteamIconPath = Path.Combine(_steamPath, @"steam", @"games", String.Concat(common.Value, @".ico")); } else if (common.Name == "type") { - Debug.WriteLine($"App: {app.AppID} - Common {common.Name}: {common.Value}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: type: App: {app.AppID} - Common {common.Name}: {common.Value}"); + steamAppType = common.Value.ToString(); + } + else + { + logger.Trace($"SteamLibrary/LoadInstalledGames: Found unrecognised line App: {app.AppID} - Common {common.Name}: {common.Value}"); } } } @@ -441,7 +489,7 @@ namespace DisplayMagician.GameLibraries if (config.Name == "installdir") { - Debug.WriteLine($"App: {detectedAppID} - Config {config.Name}: {config.Value}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Found installdir App: {detectedAppID} - Config {config.Name}: {config.Value}"); steamGameAppInfo.GameInstallDir = config.Value.ToString(); } else if (config.Name == "launch") @@ -452,7 +500,7 @@ namespace DisplayMagician.GameLibraries { if (launch_num.Name == "executable") { - Debug.WriteLine($"App: {detectedAppID} - Config - Launch {launch.Name} - {launch_num.Name}: {launch_num.Value}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Found launch executable App: {detectedAppID} - Config - Launch {launch.Name} - {launch_num.Name}: {launch_num.Value}"); steamGameAppInfo.GameExes.Add(launch_num.Value.ToString()); } @@ -463,27 +511,40 @@ namespace DisplayMagician.GameLibraries } } - steamAppInfo.Add(detectedAppID, steamGameAppInfo); + // Only store the app if it's a game! + if (steamAppType.Equals("Game",StringComparison.OrdinalIgnoreCase)) + { + steamAppInfo.Add(detectedAppID, steamGameAppInfo); + logger.Trace($"SteamLibrary/LoadInstalledGames: Adding Game with ID {detectedAppID} to the list of games"); + } + } catch (ArgumentException ex) { - Console.WriteLine($"SteamGame/GetAllInstalledGames exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); + logger.Warn(ex, $"SteamLibrary/LoadInstalledGames: ArgumentException while processing the {appInfoVdfFile} VDF file"); //we just want to ignore it if we try to add it twice.... } - Debug.WriteLine($"App: {detectedAppID} - Token: {app.Token}"); + logger.Trace($"SteamLibrary/LoadInstalledGames: Found end of loop App: {detectedAppID} - Token: {app.Token}"); } } + // Now we access the config.vdf that lives in the Steam Config file, as that lists all // the SteamLibraries. We need to find out where they areso we can interrogate them _steamConfigVdfFile = Path.Combine(_steamPath, "config", "config.vdf"); string steamConfigVdfText = File.ReadAllText(_steamConfigVdfFile, Encoding.UTF8); + logger.Trace($"SteamLibrary/LoadInstalledGames: Processing the {_steamConfigVdfFile} VDF file"); + List steamLibrariesPaths = new List(); - // Now we have to parse the config.vdf looking for the location of the SteamLibraries + // We add the default library which is based on where Steam was installed + logger.Info($"SteamLibrary/LoadInstalledGames: Found original steam library {_steamPath}"); + steamLibrariesPaths.Add(_steamPath); + + // Now we have to parse the config.vdf looking for the location of any additional SteamLibraries // We look for lines similar to this: "BaseInstallFolder_1" "E:\\SteamLibrary" // There may be multiple so we need to check the whole file Regex steamLibrariesRegex = new Regex(@"""BaseInstallFolder_\d+""\s+""(.*)""", RegexOptions.IgnoreCase); @@ -495,7 +556,7 @@ namespace DisplayMagician.GameLibraries if (steamLibraryMatch.Success) { string steamLibraryPath = Regex.Unescape(steamLibraryMatch.Groups[1].Value); - Debug.WriteLine($"Found steam library: {steamLibraryPath}"); + logger.Info($"SteamLibrary/LoadInstalledGames: Found additional steam library {steamLibraryPath}"); steamLibrariesPaths.Add(steamLibraryPath); } } @@ -509,6 +570,7 @@ namespace DisplayMagician.GameLibraries // Go through each app and extract it's details foreach (string steamLibraryAppManifestFilename in steamLibraryAppManifestFilenames) { + logger.Trace($"SteamLibrary/LoadInstalledGames: Found {steamLibraryAppManifestFilename} app manifest within steam library {steamLibraryPath}"); // Read in the contents of the file string steamLibraryAppManifestText = File.ReadAllText(steamLibraryAppManifestFilename); // Grab the appid from the file @@ -516,90 +578,101 @@ namespace DisplayMagician.GameLibraries Match appidMatches = appidRegex.Match(steamLibraryAppManifestText); if (appidMatches.Success) { - string steamGameId = appidMatches.Groups[1].Value; - // Check if this game is one that was installed - if (steamAppInfo.ContainsKey(steamGameId)) + if (int.TryParse(appidMatches.Groups[1].Value, out int steamGameId)) { - // This game is an installed game! so we start to populate it with data! - string steamGameExe = ""; + logger.Trace($"SteamLibrary/LoadInstalledGames: Found Steam Game ID {steamGameId} within {steamLibraryAppManifestFilename} steam app manifest within steam library {steamLibraryPath}"); + // Check if this game is one that was installed + if (steamAppInfo.ContainsKey(steamGameId)) + { + logger.Trace($"SteamLibrary/LoadInstalledGames: Steam Game ID {steamGameId} is installed within steam library {steamLibraryPath}!"); + // This game is an installed game! so we start to populate it with data! + string steamGameExe = ""; string steamGameName = steamAppInfo[steamGameId].GameName; // Construct the full path to the game dir from the appInfo and libraryAppManifest data string steamGameInstallDir = Path.Combine(steamLibraryPath, @"steamapps", @"common", steamAppInfo[steamGameId].GameInstallDir); - // And finally we try to populate the 'where', to see what gets run - // And so we can extract the process name - if (steamAppInfo[steamGameId].GameExes.Count > 0) - { - foreach (string gameExe in steamAppInfo[steamGameId].GameExes) + logger.Trace($"SteamLibrary/LoadInstalledGames: Looking for Steam Game ID {steamGameId} at {steamGameInstallDir }"); + + // And finally we try to populate the 'where', to see what gets run + // And so we can extract the process name + if (steamAppInfo[steamGameId].GameExes.Count > 0) { - steamGameExe = Path.Combine(steamGameInstallDir, gameExe); - // If the game executable exists, then we can proceed - if (File.Exists(steamGameExe)) + foreach (string gameExe in steamAppInfo[steamGameId].GameExes) { - break; + steamGameExe = Path.Combine(steamGameInstallDir, gameExe); + logger.Trace($"SteamLibrary/LoadInstalledGames: Looking for Steam Game Exe {steamGameExe} for Steam Game ID {steamGameId} at {steamGameInstallDir }"); + // If the game executable exists, then we can proceed + if (File.Exists(steamGameExe)) + { + logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Exe {steamGameExe} for Steam Game ID {steamGameId} at {steamGameInstallDir }"); + break; + } } + + } + + // Next, we need to get the Icons we want to use, and make sure it's the latest one. + string steamGameIconPath = ""; + // First of all, we attempt to use the Icon that Steam has cached, if it's available, as that will be updated to the latest + if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath) && steamAppInfo[steamGameId].GameSteamIconPath.EndsWith(".ico")) + { + steamGameIconPath = steamAppInfo[steamGameId].GameSteamIconPath; + logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Icon Path {steamGameIconPath} for Steam Game ID {steamGameId} at {steamGameInstallDir }"); + + } + // If there isn't an icon for us to use, then we need to extract one from the Game Executables + else if (!String.IsNullOrEmpty(steamGameExe)) + { + steamGameIconPath = steamGameExe; + logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Icon Path {steamGameIconPath} for Steam Game ID {steamGameId} at {steamGameInstallDir }"); + } + // The absolute worst case means we don't have an icon to use. SO we use the Steam one. + else + { + // And we have to make do with a Steam Icon + logger.Debug($"SteamLibrary/LoadInstalledGames: Couldn't find Steam Game Icon Path {steamGameIconPath} for Steam Game ID {steamGameId} so using default Steam Icon"); + steamGameIconPath = _steamPath; } + // And we add the Game to the list of games we have! + _allSteamGames.Add(new SteamGame(steamGameId, steamGameName, steamGameExe, steamGameIconPath)); + logger.Debug($"SteamLibrary/LoadInstalledGames: Adding Steam Game with game id {steamGameId}, name {steamGameName}, game exe {steamGameExe} and icon path {steamGameIconPath}"); } - - // Next, we need to get the Icons we want to use, and make sure it's the latest one. - string steamGameIconPath = ""; - // First of all, we attempt to use the Icon that Steam has cached, if it's available, as that will be updated to the latest - if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath) && steamAppInfo[steamGameId].GameSteamIconPath.EndsWith(".ico")) - { - steamGameIconPath = steamAppInfo[steamGameId].GameSteamIconPath; - } - // If there isn't an icon for us to use, then we need to extract one from the Game Executables - else if (!String.IsNullOrEmpty(steamGameExe)) - { - steamGameIconPath = steamGameExe; - } - // The absolute worst case means we don't have an icon to use. SO we use the Steam one. - else - { - // And we have to make do with a Steam Icon - steamGameIconPath = _steamPath; - } - - // And we add the Game to the list of games we have! - _allSteamGames.Add(new SteamGame(steamGameId, steamGameName, steamGameExe, steamGameIconPath)); - } } - } + } } + logger.Info($"SteamLibrary/LoadInstalledGames: Found {_allSteamGames.Count} installed Steam games"); + } + catch (ArgumentNullException ex) + { + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: An argument supplied to the function is null."); + } + catch (NotSupportedException ex) + { + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The invoked method is not supported or reading, seeking or writing tp a stream that isn't supported."); + } + catch (PathTooLongException ex) + { + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The path is longer than the maximum allowed by the operating system."); } catch (SecurityException ex) { - Console.WriteLine($"SteamGame/GetAllInstalledGames securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; - } - catch (UnauthorizedAccessException ex) - { - Console.WriteLine($"SteamGame/GetAllInstalledGames unauthorizedaccessexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("UnauthorizedAccessException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The user does not have the permissions required to read the Uplay InstallDir registry key."); } catch (ObjectDisposedException ex) { - Console.WriteLine($"SteamGame/GetAllInstalledGames objectdisposedexceptions: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("ObjectDisposedException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Uplay InstallDir registry key (closed keys cannot be accessed)."); } catch (IOException ex) { - Console.WriteLine($"SteamGame/GetAllInstalledGames ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - // Extract some information from this exception, and then - // throw it to the parent method. - if (ex.Source != null) - Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The Uplay InstallDir registry key has been marked for deletion so we cannot access the value dueing the UplayLibrary check."); + } + catch (UnauthorizedAccessException ex) + { + logger.Warn(ex, "SteamLibrary/GetAllInstalledGames: The user does not have the necessary registry rights to check whether Uplay is installed."); } return true; diff --git a/DisplayMagician/GameLibraries/UplayGame.cs b/DisplayMagician/GameLibraries/UplayGame.cs index 7e59f49..8cffb69 100644 --- a/DisplayMagician/GameLibraries/UplayGame.cs +++ b/DisplayMagician/GameLibraries/UplayGame.cs @@ -85,20 +85,22 @@ namespace DisplayMagician.GameLibraries foreach (Process gameProcess in gameProcesses) { try - { - if (gameProcess.MainModule.FileName.StartsWith(_uplayGameExePath)) + { + if (gameProcess.ProcessName.Equals(_uplayGameProcessName)) numGameProcesses++; } catch (Exception ex) { - logger.Debug(ex, $"UplayGame/IsRunning: Accessing Process.MainModule caused exception. Trying GameUtils.GetMainModuleFilepath instead"); + logger.Debug(ex, $"UplayGame/IsRunning: Accessing Process.ProcessName caused exception. Trying GameUtils.GetMainModuleFilepath instead"); // If there is a race condition where MainModule isn't available, then we // instead try the much slower GetMainModuleFilepath (which does the same thing) string filePath = GameUtils.GetMainModuleFilepath(gameProcess.Id); if (filePath == null) { // if we hit this bit then GameUtils.GetMainModuleFilepath failed, - // so we just skip that process + // so we just assume that the process is a game process + // as it matched the original process search + numGameProcesses++; continue; } else @@ -116,6 +118,7 @@ namespace DisplayMagician.GameLibraries } } + // Have to do much more research to figure out how to detect when Uplay is updating a game /*public override bool IsUpdating { get diff --git a/DisplayMagician/GameLibraries/UplayLibrary.cs b/DisplayMagician/GameLibraries/UplayLibrary.cs index d333b82..8857c14 100644 --- a/DisplayMagician/GameLibraries/UplayLibrary.cs +++ b/DisplayMagician/GameLibraries/UplayLibrary.cs @@ -41,6 +41,7 @@ namespace DisplayMagician.GameLibraries { try { + logger.Trace($"UplayLibrary/UplayLibrary: Uplay launcher registry key = HKLM\\{registryUplayLauncherKey}"); // Find the UplayExe location, and the UplayPath for later RegistryKey uplayInstallKey = Registry.LocalMachine.OpenSubKey(registryUplayLauncherKey, RegistryKeyPermissionCheck.ReadSubTree); if (uplayInstallKey == null) @@ -48,7 +49,15 @@ namespace DisplayMagician.GameLibraries _uplayPath = uplayInstallKey.GetValue("InstallDir", "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\").ToString(); _uplayExe = $"{_uplayPath}upc.exe"; if (File.Exists(_uplayExe)) - _isUplayInstalled = true; + { + logger.Info($"UplayLibrary/UplayLibrary: Uplay library is installed in {_uplayPath}. Found {_uplayExe}"); + _isUplayInstalled = true; + } + else + { + logger.Info($"UplayLibrary/UplayLibrary: Uplay library is not installed!"); + } + } catch (SecurityException ex) { @@ -169,8 +178,7 @@ namespace DisplayMagician.GameLibraries { logger.Debug($"UplayLibrary/RemoveUplayGame: Didn't remove Uplay game with ID {uplayGame.Name} from the Uplay Library"); return false; - } - + } else throw new UplayLibraryException(); } @@ -335,28 +343,83 @@ namespace DisplayMagician.GameLibraries if (!_isUplayInstalled) { // Uplay isn't installed, so we return an empty list. + logger.Info($"UplayLibrary/LoadInstalledGames: Uplay library is not installed"); return false; } + logger.Trace($"UplayLibrary/LoadInstalledGames: Uplay Game Installs Registry Key = HKLM\\{registryUplayInstallsKey}"); + using (RegistryKey uplayInstallKey = Registry.LocalMachine.OpenSubKey(registryUplayInstallsKey, RegistryKeyPermissionCheck.ReadSubTree)) + { + if (uplayInstallKey != null) + { + int uplayGamesInstalledCount = 0; + // Loop through the subKeys as they are the Steam Game IDs + foreach (string uplayGameKeyName in uplayInstallKey.GetSubKeyNames()) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: Found uplayGameKeyName = {uplayGameKeyName}"); + if (int.TryParse(uplayGameKeyName, out int uplayGameId)) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameKeyName is an int, so trying to see if it is a game"); + string uplayGameKeyFullName = $"{registryUplayInstallsKey}\\{uplayGameKeyName}"; + using (RegistryKey uplayGameKey = Registry.LocalMachine.OpenSubKey(uplayGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree)) + { + // If the Installed Value is set to 1, then the game is installed + // We want to keep track of that for later + if (!uplayGameKey.GetValue(@"InstallDir", "").ToString().Equals("")) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: {uplayGameKey} contains an 'InstallDir' value so is an installed Uplay Game."); + // Add this Steam App ID to the list we're keeping for later + uplayGamesInstalledCount++; + } + else + { + logger.Trace($"UplayLibrary/LoadInstalledGames: {uplayGameKey} does not contain an 'Installed' value so can't be a Uplay Game."); + } + + } + } + } + + if (uplayGamesInstalledCount == 0) + { + // There aren't any game ids so return false + logger.Warn($"UplayLibrary/LoadInstalledGames: No Uplay games installed in the Uplay library"); + return false; + } + else + { + logger.Info($"UplayLibrary/LoadInstalledGames: Found {uplayGamesInstalledCount} installed games in the Uplay library"); + } + + } + else + { + // There isnt any Uplay registry key + logger.Warn($"UplayLibrary/LoadInstalledGames: Couldn't access the Uplay Registry Key {registryUplayInstallsKey}"); + return false; + } + } // Look in HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Ubisoft\\Launcher and check the InstallDir key // That returns the location of the install dir : E:\Program Files (x86)\Ubisoft\Ubisoft Game Launcher\ - //RegistryKey uplayInstallKey = Registry.CurrentUser.OpenSubKey(registryUplayInstallsKey, RegistryKeyPermissionCheck.ReadSubTree); - //string uplayInstallDir = uplayInstallKey.GetValue("InstallDir", "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\").ToString(); - // Access {installdir}\\cache\\configuration\\configurations file string uplayConfigFilePath = _uplayPath + @"cache\configuration\configurations"; + logger.Trace($"UplayLibrary/LoadInstalledGames: Uplay Config File Path = {uplayConfigFilePath }"); string uplayConfigFileString = File.ReadAllText(uplayConfigFilePath); uplayConfigFileString = uplayConfigFileString.Remove(0, 12); + string[] dividingText = { "version: 2.0" }; + List uplayConfigFile = uplayConfigFileString.Split(dividingText,StringSplitOptions.RemoveEmptyEntries).ToList(); // Split the file into records at the SOH unicode character - List uplayConfigFile = uplayConfigFileString.Split((Char)1).ToList(); + //List uplayConfigFile = uplayConfigFileString.Split((Char)1).ToList(); // Go through every record and attempt to parse it foreach (string uplayEntry in uplayConfigFile) { // Skip any Uplay entry records that don't start with 'version:' - if (!uplayEntry.StartsWith("version:",StringComparison.OrdinalIgnoreCase)) - continue; + //if (!uplayEntry.StartsWith("version:",StringComparison.OrdinalIgnoreCase)) + // continue; + + logger.Trace($"UplayLibrary/LoadInstalledGames: Uplay Entry that starts with 'version: 2.0') = {uplayEntry}"); //Split the record into entrylines string[] delimeters = { "\r\n" }; @@ -401,17 +464,31 @@ namespace DisplayMagician.GameLibraries // for each game record grab: UplayAppInfo uplayGameAppInfo = new UplayAppInfo(); + // find the exe name looking at root: -> start_game: -> online: -> executables: -> path: -> relative: (get ACU.exe) + // Lookup the Game registry key from looking at root: -> start_game: -> online: -> executables: -> working_directory: -> register: (get HKEY_LOCAL_MACHINE\SOFTWARE\Ubisoft\Launcher\Installs\720\InstallDir) + // Extract the GameAppID from the number in the working directory (e.g. 720) + // Lookup the Game install path by reading the game registry key: D:/Ubisoft Game Launcher/Assassin's Creed Unity/ + // join the Game install path and the exe name to get the full game exe path: D:/Ubisoft Game Launcher/Assassin's Creed Unity/ACU.exe + + //if (uplayEntryLines.Find (a => a.StartsWith(" icon_image:", StringComparison.InvariantCultureIgnoreCase))) + bool gotGameIconPath = false; bool gotGameName = false; string gameFileName = ""; bool gotGameFileName = false; string gameId = ""; bool gotGameId = false; + string gameRegistryKey = ""; + bool gotGameRegistryKey = false; for (int i = 0; i <= 50; i++) { // Stop this loop once we have both filname and gameid - if (gotGameFileName && gotGameId && gotGameIconPath && gotGameName) + if (gotGameFileName && gotGameId && gotGameIconPath && gotGameName && gotGameRegistryKey) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: We got all the entries: gameFileName = {gameFileName } && gameId = {gameId } && gameIconPath = {uplayGameAppInfo.GameUplayIconPath} && gameName = {uplayGameAppInfo.GameName}"); break; + } + // This line contains the Game Name if (uplayEntryLines[i].StartsWith(" name:", StringComparison.OrdinalIgnoreCase) && !gotGameName) { @@ -422,6 +499,7 @@ namespace DisplayMagician.GameLibraries { uplayGameAppInfo.GameName = localizations[uplayGameAppInfo.GameName]; } + logger.Trace($"UplayLibrary/LoadInstalledGames: Found uplayGameAppInfo.GameName = {uplayGameAppInfo.GameName}"); gotGameName = true; } else if (uplayEntryLines[i].StartsWith(" icon_image:", StringComparison.OrdinalIgnoreCase) && !gotGameIconPath) @@ -432,12 +510,14 @@ namespace DisplayMagician.GameLibraries if (localizations.ContainsKey(iconImageFileName)) { iconImageFileName = localizations[iconImageFileName]; + logger.Trace($"UplayLibrary/LoadInstalledGames: Found iconImageFile = {iconImageFileName }"); } //61fdd16f06ae08158d0a6d476f1c6bd5.ico string uplayGameIconPath = _uplayPath + @"data\games\" + iconImageFileName; if (File.Exists(uplayGameIconPath) && uplayGameIconPath.EndsWith(".ico")) { uplayGameAppInfo.GameUplayIconPath = uplayGameIconPath; + logger.Trace($"UplayLibrary/LoadInstalledGames: Found uplayGameAppInfo.GameUplayIconPath = {uplayGameAppInfo.GameUplayIconPath }"); } gotGameIconPath = true; } @@ -447,6 +527,7 @@ namespace DisplayMagician.GameLibraries mc = Regex.Matches(uplayEntryLines[i], @"relative: (.*)"); gameFileName = mc[0].Groups[1].ToString(); gotGameFileName = true; + logger.Trace($"UplayLibrary/LoadInstalledGames: Found gameFileName = {gameFileName}"); } // This line contains the registryKey else if (uplayEntryLines[i].StartsWith(" register: HKEY_LOCAL_MACHINE") && !gotGameId) @@ -455,53 +536,95 @@ namespace DisplayMagician.GameLibraries mc = Regex.Matches(uplayEntryLines[i], @"Installs\\(\d+)\\InstallDir"); gameId = mc[0].Groups[1].ToString(); gotGameId = true; + mc = Regex.Matches(uplayEntryLines[i], @"HKEY_LOCAL_MACHINE\\(.*?)\\InstallDir"); + gameRegistryKey = mc[0].Groups[1].ToString(); + gameRegistryKey = gameRegistryKey.Replace(@"Ubisoft", @"WOW6432Node\Ubisoft"); + gotGameRegistryKey = true; + logger.Trace($"UplayLibrary/LoadInstalledGames: Found gameId = {gameId} and gameRegistryKey = {gameRegistryKey}"); } } - // Now we need to lookup the game install path in registry using the gameId - string registryUplayGameInstallsKey = registryUplayInstallsKey + "\\" + gameId; - RegistryKey uplayGameInstallKey = Registry.LocalMachine.OpenSubKey(registryUplayGameInstallsKey, RegistryKeyPermissionCheck.ReadSubTree); + logger.Trace($"UplayLibrary/LoadInstalledGames: gameId = {gameId}"); + logger.Trace($"UplayLibrary/LoadInstalledGames: gameFileName = {gameFileName}"); + logger.Trace($"UplayLibrary/LoadInstalledGames: gameGameIconPath = {uplayGameAppInfo.GameUplayIconPath}"); + logger.Trace($"UplayLibrary/LoadInstalledGames: gameRegistryKey = {gameRegistryKey}"); - // From that we lookup the actual game path - uplayGameAppInfo.GameInstallDir = Path.GetFullPath(uplayGameInstallKey.GetValue("InstallDir", "").ToString()).TrimEnd('\\'); - uplayGameAppInfo.GameExe = Path.Combine(uplayGameAppInfo.GameInstallDir,gameFileName); - uplayGameAppInfo.GameID = gameId; + if (gotGameRegistryKey) + { + // Now we need to lookup the game install path in registry using the game reg we got above + // We assume its 64-bit OS too (not 32bit) + using (RegistryKey uplayGameInstallKey = Registry.LocalMachine.OpenSubKey(gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree)) + { + // If the key doesn't exist we skip it as the game isn't installed any longer! + if (uplayGameInstallKey == null) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: Skipping Uplay Game {uplayGameAppInfo.GameName} as it isn't installed at the moment (it was uninstalled at some point)"); + continue; + } - // Then we have the gameID, the thumbimage, the icon, the name, the exe path - // And we add the Game to the list of games we have! - _allUplayGames.Add(new UplayGame(uplayGameAppInfo.GameID, uplayGameAppInfo.GameName, uplayGameAppInfo.GameExe, uplayGameAppInfo.GameUplayIconPath)); + // If we get here, then we have a real game. + foreach (string regKeyName in uplayGameInstallKey.GetValueNames()) + { + logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameInstallKey[{regKeyName}] = {uplayGameInstallKey.GetValue(regKeyName)}"); + } + + // From that we lookup the actual game path + string gameInstallDir = uplayGameInstallKey.GetValue("InstallDir", "").ToString(); + logger.Trace($"UplayLibrary/LoadInstalledGames: gameInstallDir found = {gameInstallDir}"); + if (!String.IsNullOrWhiteSpace(gameInstallDir)) + { + uplayGameAppInfo.GameInstallDir = Path.GetFullPath(gameInstallDir).TrimEnd('\\'); + logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameAppInfo.GameInstallDir = {uplayGameAppInfo.GameInstallDir }"); + uplayGameAppInfo.GameExe = Path.Combine(uplayGameAppInfo.GameInstallDir, gameFileName); + logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameAppInfo.GameExe = {uplayGameAppInfo.GameExe }"); + uplayGameAppInfo.GameID = int.Parse(gameId); + logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameAppInfo.GameID = {uplayGameAppInfo.GameID }"); + } + else + { + logger.Warn($"UplayLibrary/LoadInstalledGames: gameInstallDir is null or all whitespace!"); + } + + // Then we have the gameID, the thumbimage, the icon, the name, the exe path + // And we add the Game to the list of games we have! + _allUplayGames.Add(new UplayGame(uplayGameAppInfo.GameID, uplayGameAppInfo.GameName, uplayGameAppInfo.GameExe, uplayGameAppInfo.GameUplayIconPath)); + logger.Debug($"UplayLibrary/LoadInstalledGames: Adding Uplay Game with game id {uplayGameAppInfo.GameID}, name {uplayGameAppInfo.GameName}, game exe {uplayGameAppInfo.GameExe} and icon path {uplayGameAppInfo.GameUplayIconPath}"); + } + } + } + logger.Info($"UplayLibrary/LoadInstalledGames: Found {_allUplayGames.Count} installed Uplay games"); + + } + + catch (ArgumentNullException ex) + { + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: An argument supplied to the function is null."); + } + catch (NotSupportedException ex) + { + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The invoked method is not supported or reading, seeking or writing tp a stream that isn't supported."); + } + catch (PathTooLongException ex) + { + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The path is longer than the maximum allowed by the operating system."); } catch (SecurityException ex) { - Console.WriteLine($"UplayGame/GetAllInstalledGames securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; - } - catch (UnauthorizedAccessException ex) - { - Console.WriteLine($"UplayGame/GetAllInstalledGames unauthorizedaccessexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("UnauthorizedAccessException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The user does not have the permissions required to read the Uplay InstallDir registry key."); } catch (ObjectDisposedException ex) { - Console.WriteLine($"UplayGame/GetAllInstalledGames objectdisposedexceptions: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - if (ex.Source != null) - Console.WriteLine("ObjectDisposedException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Uplay InstallDir registry key (closed keys cannot be accessed)."); } catch (IOException ex) { - Console.WriteLine($"UplayGame/GetAllInstalledGames ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); - // Extract some information from this exception, and then - // throw it to the parent method. - if (ex.Source != null) - Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message); - throw; + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The Uplay InstallDir registry key has been marked for deletion so we cannot access the value dueing the UplayLibrary check."); + } + catch (UnauthorizedAccessException ex) + { + logger.Warn(ex, "UplayLibrary/GetAllInstalledGames: The user does not have the necessary registry rights to check whether Uplay is installed."); } return true; diff --git a/DisplayMagician/Program.cs b/DisplayMagician/Program.cs index 42f081f..08036b2 100644 --- a/DisplayMagician/Program.cs +++ b/DisplayMagician/Program.cs @@ -158,6 +158,42 @@ namespace DisplayMagician { // Start the Log file logger.Info($"Starting {Application.ProductName} v{Application.ProductVersion}"); + // Create the other DM Dir if it doesn't exist so that it's avilable for all + // parts of the program to use + if (!Directory.Exists(AppIconPath)) + { + try + { + Directory.CreateDirectory(AppIconPath); + } + catch (Exception ex) + { + logger.Error(ex, $"Program/StartUpNormally exception: Cannot create the Application Icon Folder {AppLogPath}"); + } + } + if (!Directory.Exists(AppProfilePath)) + { + try + { + Directory.CreateDirectory(AppProfilePath); + } + catch (Exception ex) + { + logger.Error(ex, $"Program/StartUpNormally exception: Cannot create the Application Profile Folder {AppProfilePath}"); + } + } + if (!Directory.Exists(AppShortcutPath)) + { + try + { + Directory.CreateDirectory(AppShortcutPath); + } + catch (Exception ex) + { + logger.Error(ex, $"Program/StartUpNormally exception: Cannot create the Application Shortcut Folder {AppShortcutPath}"); + } + } + // Write the Application Name Console.WriteLine($"{Application.ProductName} v{Application.ProductVersion}"); for (int i = 0; i <= Application.ProductName.Length + Application.ProductVersion .Length; i++) @@ -687,7 +723,6 @@ namespace DisplayMagician { if (!DisplayMagician.GameLibraries.SteamLibrary.LoadInstalledGames()) { logger.Info($"Program/LoadGamesInBackground: Cannot load installed Steam Games!"); - throw new LoadingInstalledGamesException("Program/LoadGamesInBackground: Cannot load installed Steam Games!"); } Console.WriteLine("Done."); logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Steam Games (found {GameLibraries.SteamLibrary.InstalledSteamGameCount})"); @@ -711,7 +746,6 @@ namespace DisplayMagician { if (!DisplayMagician.GameLibraries.UplayLibrary.LoadInstalledGames()) { logger.Info($"Program/LoadGamesInBackground: Cannot load installed Uplay Games!"); - throw new LoadingInstalledGamesException("Program/LoadGamesInBackground: Cannot load installed Uplay Games!"); } Console.WriteLine("Done."); logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Uplay Games (found {GameLibraries.UplayLibrary.InstalledUplayGameCount})"); diff --git a/DisplayMagician/Properties/AssemblyInfo.cs b/DisplayMagician/Properties/AssemblyInfo.cs index cba880a..87e6357 100644 --- a/DisplayMagician/Properties/AssemblyInfo.cs +++ b/DisplayMagician/Properties/AssemblyInfo.cs @@ -37,8 +37,8 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.*")] -[assembly: AssemblyFileVersion("1.0.3.0")] +[assembly: AssemblyVersion("1.0.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/DisplayMagician/ShortcutItem.cs b/DisplayMagician/ShortcutItem.cs index 42fe8dd..7f9672d 100644 --- a/DisplayMagician/ShortcutItem.cs +++ b/DisplayMagician/ShortcutItem.cs @@ -14,6 +14,7 @@ using System.Windows.Forms; using System.Text.RegularExpressions; using IWshRuntimeLibrary; using AudioSwitcher.AudioApi.CoreAudio; +using AudioSwitcher.AudioApi; namespace DisplayMagician { @@ -1808,17 +1809,8 @@ namespace DisplayMagician public void ReplaceShortcutIconInCache() { string newShortcutIconFilename; - if (_category == ShortcutCategory.Application) - { - // Work out the name of the shortcut we'll save. - newShortcutIconFilename = Path.Combine(Program.AppShortcutPath, String.Concat(@"executable-", _profileToUse.UUID, "-", Path.GetFileNameWithoutExtension(_executableNameAndPath), @".ico")); - - } - else - { - // Work out the name of the shortcut we'll save. - newShortcutIconFilename = Path.Combine(Program.AppShortcutPath, String.Concat(_gameLibrary.ToString().ToLower(CultureInfo.InvariantCulture), @"-", _profileToUse.UUID, "-", _gameAppId.ToString(), @".ico")); - } + // Work out the name of the shortcut we'll save. + newShortcutIconFilename = Path.Combine(Program.AppShortcutPath, $"{UUID}.ico"); // If the new shortcut icon should be named differently // then change the name of it @@ -1836,18 +1828,8 @@ namespace DisplayMagician public void SaveShortcutIconToCache() { - // Only add this set of options if the shortcut is to an standalone application - if (_category == ShortcutCategory.Application) - { - // Work out the name of the shortcut we'll save. - _savedShortcutIconCacheFilename = Path.Combine(Program.AppShortcutPath, String.Concat(@"executable-", _profileToUse.UUID, "-", Path.GetFileNameWithoutExtension(_executableNameAndPath), @".ico")); - - } - else - { - // Work out the name of the shortcut we'll save. - _savedShortcutIconCacheFilename = Path.Combine(Program.AppShortcutPath, String.Concat(_gameLibrary.ToString().ToLower(CultureInfo.InvariantCulture),@"-", _profileToUse.UUID, "-", _gameAppId.ToString(), @".ico")); - } + // Work out the name of the shortcut we'll save. + _savedShortcutIconCacheFilename = Path.Combine(Program.AppShortcutPath, $"{UUID}.ico"); MultiIcon shortcutIcon; try @@ -1858,7 +1840,7 @@ namespace DisplayMagician } catch (Exception ex) { - Console.WriteLine($"ShortcutRepository/SaveShortcutIconToCache exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); + logger.Error(ex, $"ShortcutRepository/SaveShortcutIconToCache: Exception while trying to save the Shortcut ivon."); // If we fail to create an icon based on the original executable or game // Then we use the standard DisplayMagician profile one. @@ -2090,87 +2072,135 @@ namespace DisplayMagician } } // Check the Audio Device is still valid (if one is specified) + CoreAudioController audioController = ShortcutRepository.AudioController; if (ChangeAudioDevice) { - CoreAudioController audioController = ShortcutRepository.AudioController; - IEnumerable audioDevices = audioController.GetPlaybackDevices(); - foreach (CoreAudioDevice audioDevice in audioDevices) + IEnumerable audioDevices = null; + if (audioController != null) { - if (audioDevice.FullName.Equals(AudioDevice)) + try { - if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Disabled) - { - ShortcutError error = new ShortcutError(); - error.Name = "AudioDeviceDisabled"; - error.Validity = ShortcutValidity.Warning; - error.Message = $"The Audio Device { AudioDevice} is disabled, so the shortcut '{Name}' cannot be used.You need to enable the audio device to use this shortcut, or edit the shortcut to change the audio device."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Warning; - } - if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.NotPresent) - { - ShortcutError error = new ShortcutError(); - error.Name = "AudioDeviceNotPresent"; - error.Validity = ShortcutValidity.Error; - error.Message = $"The Audio Device {AudioDevice} is not present, so the shortcut '{Name}' cannot be used."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Error; - } - if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Unplugged) - { - ShortcutError error = new ShortcutError(); - error.Name = "AudioDeviceUnplugged"; - error.Validity = ShortcutValidity.Warning; - error.Message = $"The Audio Device {AudioDevice} is unplugged, so the shortcut '{Name}' cannot be used. You need to plug in the audio device to use this shortcut, or edit the shortcut to change the audio device."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Warning; - } + audioDevices = audioController.GetPlaybackDevices(); } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutRepository/RefreshValidity: Exception trying to get all playback devices!"); + } + if (audioDevices != null) + { + foreach (CoreAudioDevice audioDevice in audioDevices) + { + if (audioDevice.FullName.Equals(AudioDevice)) + { + if (audioDevice.State == DeviceState.Disabled) + { + ShortcutError error = new ShortcutError(); + error.Name = "AudioDeviceDisabled"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Audio Device { AudioDevice} is disabled, so the shortcut '{Name}' cannot be used.You need to enable the audio device to use this shortcut, or edit the shortcut to change the audio device."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; + } + if (audioDevice.State == DeviceState.NotPresent) + { + ShortcutError error = new ShortcutError(); + error.Name = "AudioDeviceNotPresent"; + error.Validity = ShortcutValidity.Error; + error.Message = $"The Audio Device {AudioDevice} is not present, so the shortcut '{Name}' cannot be used."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Error; + } + if (audioDevice.State == DeviceState.Unplugged) + { + ShortcutError error = new ShortcutError(); + error.Name = "AudioDeviceUnplugged"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Audio Device {AudioDevice} is unplugged, so the shortcut '{Name}' cannot be used. You need to plug in the audio device to use this shortcut, or edit the shortcut to change the audio device."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; + } + } + } + } + } + else + { + ShortcutError error = new ShortcutError(); + error.Name = "AudioChipsetNotSupported"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Audio chipset isn't supported by DisplayMagician. You need to edit the shortcut to not change the audio output settings."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; } } // Check the Capture Device is still valid (if one is specified) if (ChangeCaptureDevice) { - CoreAudioController audioController = ShortcutRepository.AudioController; - IEnumerable captureDevices = audioController.GetCaptureDevices(); - foreach (CoreAudioDevice captureDevice in captureDevices) + IEnumerable captureDevices = null; + if (audioController != null) { - if (captureDevice.FullName.Equals(CaptureDevice)) + try { - if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Disabled) - { - ShortcutError error = new ShortcutError(); - error.Name = "CaptureDeviceDisabled"; - error.Validity = ShortcutValidity.Warning; - error.Message = $"The Capture Device {CaptureDevice} is disabled, so the shortcut '{Name}' cannot be used. You need to enable the capture device to use this shortcut, or edit the shortcut to change the capture device."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Warning; - } - if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.NotPresent) - { - ShortcutError error = new ShortcutError(); - error.Name = "CaptureDeviceNotPresent"; - error.Validity = ShortcutValidity.Error; - error.Message = $"The Capture Device {CaptureDevice} is not present, so the shortcut '{Name}' cannot be used."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Error; - } - if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Unplugged) - { - ShortcutError error = new ShortcutError(); - error.Name = "CaptureDeviceUnplugged"; - error.Validity = ShortcutValidity.Warning; - error.Message = $"The Capture Device {CaptureDevice} is unplugged, so the shortcut '{Name}' cannot be used. You need to plug in the capture device to use this shortcut, or edit the shortcut to change the capture device."; - _shortcutErrors.Add(error); - if (worstError != ShortcutValidity.Error) - worstError = ShortcutValidity.Warning; - } + captureDevices = audioController.GetCaptureDevices(); } + catch(Exception ex) + { + logger.Warn(ex, $"ShortcutRepository/RefreshValidity: Exception trying to get all capture devices!"); + } + + if (captureDevices != null) + { + foreach (CoreAudioDevice captureDevice in captureDevices) + { + if (captureDevice.FullName.Equals(CaptureDevice)) + { + if (captureDevice.State == DeviceState.Disabled) + { + ShortcutError error = new ShortcutError(); + error.Name = "CaptureDeviceDisabled"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Capture Device {CaptureDevice} is disabled, so the shortcut '{Name}' cannot be used. You need to enable the capture device to use this shortcut, or edit the shortcut to change the capture device."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; + } + if (captureDevice.State == DeviceState.NotPresent) + { + ShortcutError error = new ShortcutError(); + error.Name = "CaptureDeviceNotPresent"; + error.Validity = ShortcutValidity.Error; + error.Message = $"The Capture Device {CaptureDevice} is not present, so the shortcut '{Name}' cannot be used."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Error; + } + if (captureDevice.State == DeviceState.Unplugged) + { + ShortcutError error = new ShortcutError(); + error.Name = "CaptureDeviceUnplugged"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Capture Device {CaptureDevice} is unplugged, so the shortcut '{Name}' cannot be used. You need to plug in the capture device to use this shortcut, or edit the shortcut to change the capture device."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; + } + } + } + } + } + else + { + ShortcutError error = new ShortcutError(); + error.Name = "AudioChipsetNotSupported"; + error.Validity = ShortcutValidity.Warning; + error.Message = $"The Audio chipset isn't supported by DisplayMagician. You need to edit the shortcut to not change the microphone input settings."; + _shortcutErrors.Add(error); + if (worstError != ShortcutValidity.Error) + worstError = ShortcutValidity.Warning; } } @@ -2227,6 +2257,7 @@ namespace DisplayMagician shortcutFileName = Path.ChangeExtension(shortcutFileName, @"lnk"); // And we use the Icon from the shortcutIconCache + SaveShortcutIconToCache(); shortcutIconFileName = SavedShortcutIconCacheFilename; // If the user supplied a file diff --git a/DisplayMagician/ShortcutRepository.cs b/DisplayMagician/ShortcutRepository.cs index 59f4029..eb4e828 100644 --- a/DisplayMagician/ShortcutRepository.cs +++ b/DisplayMagician/ShortcutRepository.cs @@ -1,4 +1,5 @@ -using AudioSwitcher.AudioApi.CoreAudio; +using AudioSwitcher.AudioApi; +using AudioSwitcher.AudioApi.CoreAudio; using DisplayMagician.GameLibraries; using DisplayMagician.InterProcess; using DisplayMagicianShared; @@ -44,35 +45,24 @@ namespace DisplayMagician try { NvAPIWrapper.NVIDIA.Initialize(); - _audioController = new CoreAudioController(); - - // Create the Profile Storage Path if it doesn't exist so that it's avilable for all the program - if (!Directory.Exists(AppShortcutStoragePath)) - { - Directory.CreateDirectory(AppShortcutStoragePath); - } - } - catch (UnauthorizedAccessException ex) - { - logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician doesn't have permissions to create the Shortcut storage folder {AppShortcutStoragePath}."); - } - catch (ArgumentException ex) - { - logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} due to an invalid argument."); - } - catch (PathTooLongException ex) - { - logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} as the path is too long."); - } - catch (DirectoryNotFoundException ex) - { - logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} as the parent folder isn't there."); } catch (Exception ex) { logger.Warn(ex, $"ShortcutRepository/ShortcutRepository: Initialising NVIDIA NvAPIWrapper or CoreAudioController caused an exception."); } + try + { + _audioController = new CoreAudioController(); + } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutRepository/ShortcutRepository: Exception while trying to initialise CoreAudioController. Audio Chipset on your computer is not supported. You will be unable to set audio settings."); + } + + //_audioController.DefaultPlaybackDevice.SetAsDefault(); + //_audioController.DefaultCaptureDevice.SetAsDefault(); + // Load the Shortcuts from storage LoadShortcuts(); @@ -149,7 +139,7 @@ namespace DisplayMagician #region Class Methods public static bool AddShortcut(ShortcutItem shortcut) { - logger.Debug($"ShortcutRepository/AddShortcut: Adding shortcut {shortcut.Name} to our shortcut repository"); + logger.Trace($"ShortcutRepository/AddShortcut: Adding shortcut {shortcut.Name} to our shortcut repository"); if (!(shortcut is ShortcutItem)) return false; @@ -172,7 +162,7 @@ namespace DisplayMagician public static bool RemoveShortcut(ShortcutItem shortcut) { - logger.Debug($"ShortcutRepository/RemoveShortcut: Removing shortcut {shortcut.Name} if it exists in our shortcut repository"); + logger.Trace($"ShortcutRepository/RemoveShortcut: Removing shortcut {shortcut.Name} if it exists in our shortcut repository"); if (!(shortcut is ShortcutItem)) return false; @@ -199,12 +189,12 @@ namespace DisplayMagician { SaveShortcuts(); IsValidRefresh(); - logger.Debug($"ShortcutRepository/RemoveShortcut: Our shortcut repository does contain a shortcut we were looking for"); + logger.Trace($"ShortcutRepository/RemoveShortcut: Our shortcut repository does contain a shortcut we were looking for"); return true; } else if (numRemoved == 0) { - logger.Debug($"ShortcutRepository/RemoveShortcut: Our shortcut repository doesn't contain a shortcut we were looking for"); + logger.Trace($"ShortcutRepository/RemoveShortcut: Our shortcut repository doesn't contain a shortcut we were looking for"); return false; } @@ -216,7 +206,7 @@ namespace DisplayMagician public static bool RemoveShortcut(string shortcutNameOrUuid) { - logger.Debug($"ShortcutRepository/RemoveShortcut2: Removing shortcut {shortcutNameOrUuid} if it exists in our shortcut repository"); + logger.Trace($"ShortcutRepository/RemoveShortcut2: Removing shortcut {shortcutNameOrUuid} if it exists in our shortcut repository"); if (String.IsNullOrWhiteSpace(shortcutNameOrUuid)) { @@ -255,12 +245,12 @@ namespace DisplayMagician { SaveShortcuts(); IsValidRefresh(); - logger.Debug($"ShortcutRepository/RemoveShortcut2: Our shortcut repository does contain a shortcut with Name or UUID {shortcutNameOrUuid}"); + logger.Trace($"ShortcutRepository/RemoveShortcut2: Our shortcut repository does contain a shortcut with Name or UUID {shortcutNameOrUuid}"); return true; } else if (numRemoved == 0) { - logger.Debug($"ShortcutRepository/RemoveShortcut2: Our shortcut repository doesn't contain a shortcut with Name or UUID {shortcutNameOrUuid}"); + logger.Trace($"ShortcutRepository/RemoveShortcut2: Our shortcut repository doesn't contain a shortcut with Name or UUID {shortcutNameOrUuid}"); return false; } else @@ -272,7 +262,7 @@ namespace DisplayMagician public static bool ContainsShortcut(ShortcutItem shortcut) { - logger.Debug($"ShortcutRepository/ContainsShortcut: Checking whether {shortcut.Name} exists in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut: Checking whether {shortcut.Name} exists in our shortcut repository"); if (!(shortcut is ShortcutItem)) return false; @@ -281,7 +271,7 @@ namespace DisplayMagician { if (testShortcut.UUID.Equals(shortcut.UUID, StringComparison.OrdinalIgnoreCase)) { - logger.Debug($"ShortcutRepository/ContainsShortcut: {shortcut.Name} does exist in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut: {shortcut.Name} does exist in our shortcut repository"); return true; } } @@ -292,7 +282,7 @@ namespace DisplayMagician public static bool ContainsShortcut(string shortcutNameOrUuid) { - logger.Debug($"ShortcutRepository/ContainsShortcut2: Checking whether {shortcutNameOrUuid} exists in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut2: Checking whether {shortcutNameOrUuid} exists in our shortcut repository"); if (String.IsNullOrWhiteSpace(shortcutNameOrUuid)) { @@ -307,7 +297,7 @@ namespace DisplayMagician { if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase)) { - logger.Debug($"ShortcutRepository/ContainsShortcut2: Shortcut with UUID {shortcutNameOrUuid} does exist in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut2: Shortcut with UUID {shortcutNameOrUuid} does exist in our shortcut repository"); return true; } } @@ -319,14 +309,14 @@ namespace DisplayMagician { if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase)) { - logger.Debug($"ShortcutRepository/ContainsShortcut2: Shortcut with name {shortcutNameOrUuid} does exist in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut2: Shortcut with name {shortcutNameOrUuid} does exist in our shortcut repository"); return true; } } } - logger.Debug($"ShortcutRepository/ContainsShortcut2: Shortcut with name {shortcutNameOrUuid} doesn't exist in our shortcut repository"); + logger.Trace($"ShortcutRepository/ContainsShortcut2: Shortcut with name {shortcutNameOrUuid} doesn't exist in our shortcut repository"); return false; } @@ -334,7 +324,7 @@ namespace DisplayMagician public static ShortcutItem GetShortcut(string shortcutNameOrUuid) { - logger.Debug($"ShortcutRepository/GetShortcut: Finding and returning {shortcutNameOrUuid} if it exists in our shortcut repository"); + logger.Trace($"ShortcutRepository/GetShortcut: Finding and returning {shortcutNameOrUuid} if it exists in our shortcut repository"); if (String.IsNullOrWhiteSpace(shortcutNameOrUuid)) { @@ -349,7 +339,7 @@ namespace DisplayMagician { if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase)) { - logger.Debug($"ShortcutRepository/GetShortcut: Returning shortcut with UUID {shortcutNameOrUuid}"); + logger.Trace($"ShortcutRepository/GetShortcut: Returning shortcut with UUID {shortcutNameOrUuid}"); return testShortcut; } } @@ -361,14 +351,14 @@ namespace DisplayMagician { if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase)) { - logger.Debug($"ShortcutRepository/GetShortcut: Returning shortcut with Name {shortcutNameOrUuid}"); + logger.Trace($"ShortcutRepository/GetShortcut: Returning shortcut with Name {shortcutNameOrUuid}"); return testShortcut; } } } - logger.Debug($"ShortcutRepository/GetShortcut: No shortcut was found to return with UUI or Name {shortcutNameOrUuid}"); + logger.Trace($"ShortcutRepository/GetShortcut: No shortcut was found to return with UUID or Name {shortcutNameOrUuid}"); return null; } @@ -620,96 +610,162 @@ namespace DisplayMagician } - // record the old audio device + // Get the list of Audio Devices currently connected and active bool needToChangeAudioDevice = false; - CoreAudioDevice rollbackAudioDevice = _audioController.DefaultPlaybackDevice; + CoreAudioDevice rollbackAudioDevice = null; double rollbackAudioVolume = 50; - if (rollbackAudioDevice != null) - { - rollbackAudioVolume = _audioController.DefaultPlaybackDevice.Volume; - if (!rollbackAudioDevice.FullName.Equals(shortcutToUse.AudioDevice)) - { - logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.AudioDevice} audio device."); - needToChangeAudioDevice = true; - } - else - { - logger.Debug($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.AudioDevice} audio device so no need to change audio devices."); - } - } - - // Change Audio Device (if one specified) - if (shortcutToUse.ChangeAudioDevice) - { - logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.AudioDevice} audio device."); - - IEnumerable audioDevices = _audioController.GetPlaybackDevices(); - foreach (CoreAudioDevice audioDevice in audioDevices) - { - if (audioDevice.FullName.Equals(shortcutToUse.AudioDevice)) - { - // use the Audio Device - audioDevice.SetAsDefault(); - - if (shortcutToUse.SetAudioVolume) - { - logger.Debug($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.AudioDevice} audio level to {shortcutToUse.AudioVolume}%."); - Task myTask = new Task(() => - { - audioDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.AudioVolume)); - }); - myTask.Start(); - myTask.Wait(2000); - } - - } - } - } - - // record the old microphone device + List activeAudioDevices = new List(); bool needToChangeCaptureDevice = false; - CoreAudioDevice rollbackCaptureDevice = _audioController.DefaultCaptureDevice; + CoreAudioDevice rollbackCaptureDevice = null; double rollbackCaptureVolume = 50; - if (rollbackCaptureDevice != null) - { - rollbackCaptureVolume = _audioController.DefaultCaptureDevice.Volume; - if (!rollbackCaptureDevice.FullName.Equals(shortcutToUse.CaptureDevice)) - { - logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.CaptureDevice} capture (microphone) device."); - needToChangeCaptureDevice = true; - } - else - { - logger.Debug($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.CaptureDevice} capture (microphone) device so no need to change capture devices."); - } - } - - // Change capture Device (if one specified) - if (shortcutToUse.ChangeCaptureDevice) - { - logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.CaptureDevice} capture (microphone) device."); + List activeCaptureDevices = new List(); - IEnumerable captureDevices = _audioController.GetCaptureDevices(); - foreach (CoreAudioDevice captureDevice in captureDevices) - { - if (captureDevice.FullName.Equals(shortcutToUse.CaptureDevice)) + if (_audioController != null) + { + try { + activeAudioDevices = _audioController.GetPlaybackDevices(DeviceState.Active).ToList(); + if (activeAudioDevices.Count > 0) { - // use the Audio Device - captureDevice.SetAsDefault(); - - if (shortcutToUse.SetCaptureVolume) + // Change Audio Device (if one specified) + if (shortcutToUse.ChangeAudioDevice && !shortcutToUse.AudioDevice.Equals("")) { - logger.Debug($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.CaptureDevice} audio level to {shortcutToUse.CaptureVolume}%."); - Task myTask = new Task(() => - { - captureDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.CaptureVolume)); - }); - myTask.Start(); - myTask.Wait(2000); - } + // record the old audio device + rollbackAudioDevice = _audioController.DefaultPlaybackDevice; + if (rollbackAudioDevice != null) + { + rollbackAudioVolume = _audioController.DefaultPlaybackDevice.Volume; + if (!rollbackAudioDevice.FullName.Equals(shortcutToUse.AudioDevice)) + { + logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.AudioDevice} audio device."); + needToChangeAudioDevice = true; + } + + } + + if (needToChangeAudioDevice) + { + logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.AudioDevice} audio device."); + + foreach (CoreAudioDevice audioDevice in activeAudioDevices) + { + if (audioDevice.FullName.Equals(shortcutToUse.AudioDevice)) + { + // use the Audio Device + audioDevice.SetAsDefault(); + } + } + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.AudioDevice} audio device so no need to change audio devices."); + } + + if (shortcutToUse.SetAudioVolume) + { + logger.Info($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.AudioDevice} volume level to {shortcutToUse.AudioVolume}%."); + Task myTask = new Task(() => + { + _audioController.DefaultPlaybackDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.AudioVolume)); + }); + myTask.Start(); + myTask.Wait(2000); + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: We don't need to set the {shortcutToUse.AudioDevice} volume level."); + } + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: Shortcut does not require changing Audio Device."); + } + } + else + { + logger.Warn($"ShortcutRepository/RunShortcut: No active Audio Devices to use so skipping audio device checks!"); } } + catch(Exception ex) + { + logger.Warn(ex, $"ShortcutRepository/RunShortcut: Exception accessing or manipulating Audio Devices!"); + } + + + try + { + // Get the list of Audio Devices currently connected + activeCaptureDevices = _audioController.GetCaptureDevices(DeviceState.Active).ToList(); + if (activeCaptureDevices.Count > 0) + { + + // Change capture Device (if one specified) + if (shortcutToUse.ChangeCaptureDevice && !shortcutToUse.CaptureDevice.Equals("")) + { + // record the old microphone device + rollbackCaptureDevice = _audioController.DefaultCaptureDevice; + if (rollbackCaptureDevice != null) + { + rollbackCaptureVolume = _audioController.DefaultCaptureDevice.Volume; + if (!rollbackCaptureDevice.FullName.Equals(shortcutToUse.CaptureDevice)) + { + logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.CaptureDevice} capture (microphone) device."); + needToChangeCaptureDevice = true; + } + } + + if (needToChangeCaptureDevice) + { + logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.CaptureDevice} capture (microphone) device."); + + foreach (CoreAudioDevice captureDevice in activeCaptureDevices) + { + if (captureDevice.FullName.Equals(shortcutToUse.CaptureDevice)) + { + // use the Audio Device + captureDevice.SetAsDefault(); + } + } + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.CaptureDevice} capture (microphone) device so no need to change capture devices."); + } + + if (shortcutToUse.SetCaptureVolume) + { + logger.Info($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.CaptureDevice} capture (microphone) level to {shortcutToUse.CaptureVolume}%."); + Task myTask = new Task(() => + { + _audioController.DefaultCaptureDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.CaptureVolume)); + }); + myTask.Start(); + myTask.Wait(2000); + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: We don't need to set the {shortcutToUse.CaptureDevice} capture (microphone) volume level."); + } + + } + else + { + logger.Info($"ShortcutRepository/RunShortcut: Shortcut does not require changing capture (microphone) device."); + } + } + else + { + logger.Warn($"ShortcutRepository/RunShortcut: No active Capture Devices to use so skipping capture device checks!"); + } + } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutRepository/RunShortcut: Exception accessing or manipulating Capture Devices!"); + } + } + else + { + logger.Warn($"ShortcutRepository/RunShortcut: CoreAudio Controller is null, so we can't set Audio or Capture Devices!"); } // Set the IP Service status back to what it was @@ -777,7 +833,7 @@ namespace DisplayMagician } else { - logger.Debug($"ShortcutRepository/RunShortcut: No programs to start before the main game or executable"); + logger.Info($"ShortcutRepository/RunShortcut: No programs to start before the main game or executable"); } // Add a status notification icon in the status area @@ -887,7 +943,7 @@ namespace DisplayMagician // Now look for the thing we're supposed to monitor // and wait until it starts up List processesToMonitor = new List(); - for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500) + for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500) { // Look for the processes with the ProcessName we sorted out earlier processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList(); @@ -1021,7 +1077,7 @@ namespace DisplayMagician Thread.Sleep(500); // Wait for Steam game to update if needed - for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500) + for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500) { if (!steamGameToRun.IsUpdating) @@ -1162,17 +1218,21 @@ namespace DisplayMagician // Wait for Uplay to start List uplayProcesses = null; - for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500) + for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500) { - // Look for the processes with the ProcessName we sorted out earlier - uplayProcesses = Process.GetProcessesByName("upc").ToList(); + // Look for the processes with the UplayGameLauncher name as those are the ones that launch the game + // Look for the 32 bit games processes + uplayProcesses = Process.GetProcessesByName("UbisoftGameLauncher").ToList(); + // Look for the 64 bit games processes + uplayProcesses.AddRange(Process.GetProcessesByName("UbisoftGameLauncher64").ToList()); // If we have found one or more processes then we should be good to go // so let's break if (uplayProcesses.Count > 0) { - logger.Debug($"ShortcutRepository/RunShortcut: Found {uplayProcesses.Count} 'upc' processes have started"); + Thread.Sleep(500); + logger.Debug($"ShortcutRepository/RunShortcut: Found {uplayProcesses.Count} 'UplayGameLauncher' processes have started"); break; } @@ -1182,13 +1242,11 @@ namespace DisplayMagician } - // Delay 5secs - Thread.Sleep(5000); - logger.Debug($"ShortcutRepository/RunShortcut: Pausing for 5 seconds to let the Uplay process start the game."); + //logger.Debug($"ShortcutRepository/RunShortcut: Pausing for 5 seconds to let the Uplay process start the game, and update it if necessary."); // Now we know the Uplay app is running then // we wait until the Uplay game is running (*allows for uplay update) - for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500) + for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500) { if (uplayGameToRun.IsRunning) @@ -1527,43 +1585,65 @@ namespace DisplayMagician } // Change Audio Device back (if one specified) - if (needToChangeAudioDevice) + if (activeAudioDevices.Count > 0) { - logger.Debug($"ShortcutRepository/RunShortcut: Reverting default audio back to {rollbackAudioDevice.Name} audio device"); - // use the Audio Device - rollbackAudioDevice.SetAsDefault(); - - if (shortcutToUse.SetAudioVolume) + if (needToChangeAudioDevice) { - logger.Debug($"ShortcutRepository/RunShortcut: Reverting default audio volume back to {shortcutToUse.SetAudioVolume}% volume"); - Task myTask = new Task(() => - { - rollbackAudioDevice.SetVolumeAsync(Convert.ToDouble(rollbackAudioVolume)); - }); - myTask.Start(); - myTask.Wait(2000); - } + logger.Debug($"ShortcutRepository/RunShortcut: Reverting default audio back to {rollbackAudioDevice.Name} audio device"); + // use the Audio Device + rollbackAudioDevice.SetAsDefault(); + if (shortcutToUse.SetAudioVolume) + { + logger.Debug($"ShortcutRepository/RunShortcut: Reverting default audio volume back to {shortcutToUse.SetAudioVolume}% volume"); + Task myTask = new Task(() => + { + rollbackAudioDevice.SetVolumeAsync(Convert.ToDouble(rollbackAudioVolume)); + }); + myTask.Start(); + myTask.Wait(2000); + } + } + else + { + logger.Debug($"ShortcutRepository/RunShortcut: Shortcut did not require changing Audio Device, so no need to change it back."); + } + } + else + { + logger.Debug($"ShortcutRepository/RunShortcut: No Audio Devices active, so no need to change them back."); } + // Change Capture Device back (if one specified) - if (needToChangeCaptureDevice) + if (activeCaptureDevices.Count > 0) { - logger.Debug($"ShortcutRepository/RunShortcut: Reverting default capture (microphone) device back to {rollbackCaptureDevice.Name} capture device"); - // use the Audio Device - rollbackCaptureDevice.SetAsDefault(); - - if (shortcutToUse.SetCaptureVolume) + if (needToChangeCaptureDevice) { - logger.Debug($"ShortcutRepository/RunShortcut: Reverting default capture (microphone) volume back to {shortcutToUse.SetAudioVolume}% volume"); - Task myTask = new Task(() => - { - rollbackCaptureDevice.SetVolumeAsync(Convert.ToDouble(rollbackCaptureVolume)); - }); - myTask.Start(); - myTask.Wait(2000); - } + logger.Debug($"ShortcutRepository/RunShortcut: Reverting default capture (microphone) device back to {rollbackCaptureDevice.Name} capture device"); + // use the Audio Device + rollbackCaptureDevice.SetAsDefault(); + if (shortcutToUse.SetCaptureVolume) + { + logger.Debug($"ShortcutRepository/RunShortcut: Reverting default capture (microphone) volume back to {shortcutToUse.SetAudioVolume}% volume"); + Task myTask = new Task(() => + { + rollbackCaptureDevice.SetVolumeAsync(Convert.ToDouble(rollbackCaptureVolume)); + }); + myTask.Start(); + myTask.Wait(2000); + } + + } + else + { + logger.Debug($"ShortcutRepository/RunShortcut: Shortcut did not require changing Capture Device, so no need to change it back."); + } + } + else + { + logger.Debug($"ShortcutRepository/RunShortcut: No Capture Devices active, so no need to change them back."); } // Change back to the original profile only if it is different @@ -1587,6 +1667,10 @@ namespace DisplayMagician } } + else + { + logger.Debug($"ShortcutRepository/RunShortcut: Shortcut did not require changing Display Profile, so no need to change it back."); + } } diff --git a/DisplayMagician/UIForms/ShortcutForm.Designer.cs b/DisplayMagician/UIForms/ShortcutForm.Designer.cs index f352d99..3116524 100644 --- a/DisplayMagician/UIForms/ShortcutForm.Designer.cs +++ b/DisplayMagician/UIForms/ShortcutForm.Designer.cs @@ -66,6 +66,7 @@ namespace DisplayMagician.UIForms this.rb_no_change_audio = new System.Windows.Forms.RadioButton(); this.tabp_before = new System.Windows.Forms.TabPage(); this.pnl_start_program4 = new System.Windows.Forms.Panel(); + this.cb_dont_start_if_running4 = new System.Windows.Forms.CheckBox(); this.cb_start_program4 = new System.Windows.Forms.CheckBox(); this.txt_start_program4 = new System.Windows.Forms.TextBox(); this.cb_start_program_close4 = new System.Windows.Forms.CheckBox(); @@ -74,6 +75,7 @@ namespace DisplayMagician.UIForms this.cb_start_program_pass_args4 = new System.Windows.Forms.CheckBox(); this.lbl_start_program4 = new System.Windows.Forms.Label(); this.pnl_start_program3 = new System.Windows.Forms.Panel(); + this.cb_dont_start_if_running3 = new System.Windows.Forms.CheckBox(); this.cb_start_program3 = new System.Windows.Forms.CheckBox(); this.txt_start_program3 = new System.Windows.Forms.TextBox(); this.cb_start_program_close3 = new System.Windows.Forms.CheckBox(); @@ -82,6 +84,7 @@ namespace DisplayMagician.UIForms this.cb_start_program_pass_args3 = new System.Windows.Forms.CheckBox(); this.lbl_start_program3 = new System.Windows.Forms.Label(); this.pnl_start_program2 = new System.Windows.Forms.Panel(); + this.cb_dont_start_if_running2 = new System.Windows.Forms.CheckBox(); this.cb_start_program2 = new System.Windows.Forms.CheckBox(); this.txt_start_program2 = new System.Windows.Forms.TextBox(); this.cb_start_program_close2 = new System.Windows.Forms.CheckBox(); @@ -90,6 +93,7 @@ namespace DisplayMagician.UIForms this.cb_start_program_pass_args2 = new System.Windows.Forms.CheckBox(); this.lbl_start_program2 = new System.Windows.Forms.Label(); this.pnl_start_program1 = new System.Windows.Forms.Panel(); + this.cb_dont_start_if_running1 = new System.Windows.Forms.CheckBox(); this.cb_start_program1 = new System.Windows.Forms.CheckBox(); this.txt_start_program1 = new System.Windows.Forms.TextBox(); this.cb_start_program_close1 = new System.Windows.Forms.CheckBox(); @@ -142,10 +146,9 @@ namespace DisplayMagician.UIForms this.lbl_title = new System.Windows.Forms.Label(); this.lbl_shortcut_name = new System.Windows.Forms.Label(); this.cb_autosuggest = new System.Windows.Forms.CheckBox(); - this.cb_dont_start_if_running1 = new System.Windows.Forms.CheckBox(); - this.cb_dont_start_if_running2 = new System.Windows.Forms.CheckBox(); - this.cb_dont_start_if_running3 = new System.Windows.Forms.CheckBox(); - this.cb_dont_start_if_running4 = new System.Windows.Forms.CheckBox(); + this.lbl_disabled_shortcut_audio_chipset = new System.Windows.Forms.Label(); + this.lbl_no_active_audio_devices = new System.Windows.Forms.Label(); + this.lbl_no_active_capture_devices = new System.Windows.Forms.Label(); this.tabc_shortcut.SuspendLayout(); this.tabp_display.SuspendLayout(); this.tabp_audio.SuspendLayout(); @@ -321,6 +324,9 @@ namespace DisplayMagician.UIForms // tabp_audio // this.tabp_audio.BackColor = System.Drawing.Color.Black; + this.tabp_audio.Controls.Add(this.lbl_no_active_capture_devices); + this.tabp_audio.Controls.Add(this.lbl_no_active_audio_devices); + this.tabp_audio.Controls.Add(this.lbl_disabled_shortcut_audio_chipset); this.tabp_audio.Controls.Add(this.gb_capture_settings); this.tabp_audio.Controls.Add(this.gb_audio_settings); this.tabp_audio.Location = new System.Drawing.Point(4, 32); @@ -623,6 +629,19 @@ namespace DisplayMagician.UIForms this.pnl_start_program4.Size = new System.Drawing.Size(959, 124); this.pnl_start_program4.TabIndex = 19; // + // cb_dont_start_if_running4 + // + this.cb_dont_start_if_running4.AutoSize = true; + this.cb_dont_start_if_running4.ForeColor = System.Drawing.Color.White; + this.cb_dont_start_if_running4.Location = new System.Drawing.Point(167, 82); + this.cb_dont_start_if_running4.Name = "cb_dont_start_if_running4"; + this.cb_dont_start_if_running4.Size = new System.Drawing.Size(289, 24); + this.cb_dont_start_if_running4.TabIndex = 20; + this.cb_dont_start_if_running4.Text = "Don\'t start if program already running"; + this.cb_dont_start_if_running4.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.cb_dont_start_if_running4.UseVisualStyleBackColor = true; + this.cb_dont_start_if_running4.Visible = false; + // // cb_start_program4 // this.cb_start_program4.Location = new System.Drawing.Point(21, 18); @@ -713,6 +732,19 @@ namespace DisplayMagician.UIForms this.pnl_start_program3.Size = new System.Drawing.Size(959, 124); this.pnl_start_program3.TabIndex = 18; // + // cb_dont_start_if_running3 + // + this.cb_dont_start_if_running3.AutoSize = true; + this.cb_dont_start_if_running3.ForeColor = System.Drawing.Color.White; + this.cb_dont_start_if_running3.Location = new System.Drawing.Point(167, 82); + this.cb_dont_start_if_running3.Name = "cb_dont_start_if_running3"; + this.cb_dont_start_if_running3.Size = new System.Drawing.Size(289, 24); + this.cb_dont_start_if_running3.TabIndex = 20; + this.cb_dont_start_if_running3.Text = "Don\'t start if program already running"; + this.cb_dont_start_if_running3.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.cb_dont_start_if_running3.UseVisualStyleBackColor = true; + this.cb_dont_start_if_running3.Visible = false; + // // cb_start_program3 // this.cb_start_program3.Location = new System.Drawing.Point(21, 18); @@ -803,6 +835,19 @@ namespace DisplayMagician.UIForms this.pnl_start_program2.Size = new System.Drawing.Size(959, 124); this.pnl_start_program2.TabIndex = 18; // + // cb_dont_start_if_running2 + // + this.cb_dont_start_if_running2.AutoSize = true; + this.cb_dont_start_if_running2.ForeColor = System.Drawing.Color.White; + this.cb_dont_start_if_running2.Location = new System.Drawing.Point(167, 82); + this.cb_dont_start_if_running2.Name = "cb_dont_start_if_running2"; + this.cb_dont_start_if_running2.Size = new System.Drawing.Size(289, 24); + this.cb_dont_start_if_running2.TabIndex = 19; + this.cb_dont_start_if_running2.Text = "Don\'t start if program already running"; + this.cb_dont_start_if_running2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.cb_dont_start_if_running2.UseVisualStyleBackColor = true; + this.cb_dont_start_if_running2.Visible = false; + // // cb_start_program2 // this.cb_start_program2.Location = new System.Drawing.Point(21, 18); @@ -893,6 +938,19 @@ namespace DisplayMagician.UIForms this.pnl_start_program1.Size = new System.Drawing.Size(959, 124); this.pnl_start_program1.TabIndex = 0; // + // cb_dont_start_if_running1 + // + this.cb_dont_start_if_running1.AutoSize = true; + this.cb_dont_start_if_running1.ForeColor = System.Drawing.Color.White; + this.cb_dont_start_if_running1.Location = new System.Drawing.Point(167, 82); + this.cb_dont_start_if_running1.Name = "cb_dont_start_if_running1"; + this.cb_dont_start_if_running1.Size = new System.Drawing.Size(289, 24); + this.cb_dont_start_if_running1.TabIndex = 18; + this.cb_dont_start_if_running1.Text = "Don\'t start if program already running"; + this.cb_dont_start_if_running1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.cb_dont_start_if_running1.UseVisualStyleBackColor = true; + this.cb_dont_start_if_running1.Visible = false; + // // cb_start_program1 // this.cb_start_program1.Location = new System.Drawing.Point(21, 18); @@ -1525,57 +1583,55 @@ namespace DisplayMagician.UIForms this.cb_autosuggest.UseVisualStyleBackColor = true; this.cb_autosuggest.CheckedChanged += new System.EventHandler(this.cb_autosuggest_CheckedChanged); // - // cb_dont_start_if_running1 + // lbl_disabled_shortcut_audio_chipset // - this.cb_dont_start_if_running1.AutoSize = true; - this.cb_dont_start_if_running1.ForeColor = System.Drawing.Color.White; - this.cb_dont_start_if_running1.Location = new System.Drawing.Point(167, 82); - this.cb_dont_start_if_running1.Name = "cb_dont_start_if_running1"; - this.cb_dont_start_if_running1.Size = new System.Drawing.Size(289, 24); - this.cb_dont_start_if_running1.TabIndex = 18; - this.cb_dont_start_if_running1.Text = "Don\'t start if program already running"; - this.cb_dont_start_if_running1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cb_dont_start_if_running1.UseVisualStyleBackColor = true; - this.cb_dont_start_if_running1.Visible = false; + this.lbl_disabled_shortcut_audio_chipset.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.lbl_disabled_shortcut_audio_chipset.AutoSize = true; + this.lbl_disabled_shortcut_audio_chipset.BackColor = System.Drawing.Color.Brown; + this.lbl_disabled_shortcut_audio_chipset.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lbl_disabled_shortcut_audio_chipset.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); + this.lbl_disabled_shortcut_audio_chipset.ForeColor = System.Drawing.Color.White; + this.lbl_disabled_shortcut_audio_chipset.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.lbl_disabled_shortcut_audio_chipset.Location = new System.Drawing.Point(326, 298); + this.lbl_disabled_shortcut_audio_chipset.Name = "lbl_disabled_shortcut_audio_chipset"; + this.lbl_disabled_shortcut_audio_chipset.Size = new System.Drawing.Size(430, 22); + this.lbl_disabled_shortcut_audio_chipset.TabIndex = 34; + this.lbl_disabled_shortcut_audio_chipset.Text = "Unsupported Audio Chipset. Setting audio isn\'t supported :("; + this.lbl_disabled_shortcut_audio_chipset.Visible = false; // - // cb_dont_start_if_running2 + // lbl_no_active_audio_devices // - this.cb_dont_start_if_running2.AutoSize = true; - this.cb_dont_start_if_running2.ForeColor = System.Drawing.Color.White; - this.cb_dont_start_if_running2.Location = new System.Drawing.Point(167, 82); - this.cb_dont_start_if_running2.Name = "cb_dont_start_if_running2"; - this.cb_dont_start_if_running2.Size = new System.Drawing.Size(289, 24); - this.cb_dont_start_if_running2.TabIndex = 19; - this.cb_dont_start_if_running2.Text = "Don\'t start if program already running"; - this.cb_dont_start_if_running2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cb_dont_start_if_running2.UseVisualStyleBackColor = true; - this.cb_dont_start_if_running2.Visible = false; + this.lbl_no_active_audio_devices.Anchor = System.Windows.Forms.AnchorStyles.None; + this.lbl_no_active_audio_devices.AutoSize = true; + this.lbl_no_active_audio_devices.BackColor = System.Drawing.Color.Brown; + this.lbl_no_active_audio_devices.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lbl_no_active_audio_devices.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); + this.lbl_no_active_audio_devices.ForeColor = System.Drawing.Color.White; + this.lbl_no_active_audio_devices.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.lbl_no_active_audio_devices.Location = new System.Drawing.Point(131, 151); + this.lbl_no_active_audio_devices.Name = "lbl_no_active_audio_devices"; + this.lbl_no_active_audio_devices.Size = new System.Drawing.Size(804, 22); + this.lbl_no_active_audio_devices.TabIndex = 35; + this.lbl_no_active_audio_devices.Text = "No active audio outputs found. Please connect or enable at least one audio output" + + " if you want to use this feature."; + this.lbl_no_active_audio_devices.Visible = false; // - // cb_dont_start_if_running3 + // lbl_no_active_capture_devices // - this.cb_dont_start_if_running3.AutoSize = true; - this.cb_dont_start_if_running3.ForeColor = System.Drawing.Color.White; - this.cb_dont_start_if_running3.Location = new System.Drawing.Point(167, 82); - this.cb_dont_start_if_running3.Name = "cb_dont_start_if_running3"; - this.cb_dont_start_if_running3.Size = new System.Drawing.Size(289, 24); - this.cb_dont_start_if_running3.TabIndex = 20; - this.cb_dont_start_if_running3.Text = "Don\'t start if program already running"; - this.cb_dont_start_if_running3.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cb_dont_start_if_running3.UseVisualStyleBackColor = true; - this.cb_dont_start_if_running3.Visible = false; - // - // cb_dont_start_if_running4 - // - this.cb_dont_start_if_running4.AutoSize = true; - this.cb_dont_start_if_running4.ForeColor = System.Drawing.Color.White; - this.cb_dont_start_if_running4.Location = new System.Drawing.Point(167, 82); - this.cb_dont_start_if_running4.Name = "cb_dont_start_if_running4"; - this.cb_dont_start_if_running4.Size = new System.Drawing.Size(289, 24); - this.cb_dont_start_if_running4.TabIndex = 20; - this.cb_dont_start_if_running4.Text = "Don\'t start if program already running"; - this.cb_dont_start_if_running4.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cb_dont_start_if_running4.UseVisualStyleBackColor = true; - this.cb_dont_start_if_running4.Visible = false; + this.lbl_no_active_capture_devices.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.lbl_no_active_capture_devices.AutoSize = true; + this.lbl_no_active_capture_devices.BackColor = System.Drawing.Color.Brown; + this.lbl_no_active_capture_devices.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lbl_no_active_capture_devices.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); + this.lbl_no_active_capture_devices.ForeColor = System.Drawing.Color.White; + this.lbl_no_active_capture_devices.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.lbl_no_active_capture_devices.Location = new System.Drawing.Point(126, 433); + this.lbl_no_active_capture_devices.Name = "lbl_no_active_capture_devices"; + this.lbl_no_active_capture_devices.Size = new System.Drawing.Size(831, 22); + this.lbl_no_active_capture_devices.TabIndex = 36; + this.lbl_no_active_capture_devices.Text = "No active microphone inputs found. Please connect or enable at least one micropho" + + "ne if you want to use this feature."; + this.lbl_no_active_capture_devices.Visible = false; // // ShortcutForm // @@ -1606,6 +1662,7 @@ namespace DisplayMagician.UIForms this.tabp_display.ResumeLayout(false); this.tabp_display.PerformLayout(); this.tabp_audio.ResumeLayout(false); + this.tabp_audio.PerformLayout(); this.gb_capture_settings.ResumeLayout(false); this.gb_capture_settings.PerformLayout(); this.gb_capture_volume.ResumeLayout(false); @@ -1759,5 +1816,8 @@ namespace DisplayMagician.UIForms private System.Windows.Forms.CheckBox cb_dont_start_if_running3; private System.Windows.Forms.CheckBox cb_dont_start_if_running2; private System.Windows.Forms.CheckBox cb_dont_start_if_running1; + private System.Windows.Forms.Label lbl_disabled_shortcut_audio_chipset; + private System.Windows.Forms.Label lbl_no_active_audio_devices; + private System.Windows.Forms.Label lbl_no_active_capture_devices; } } \ No newline at end of file diff --git a/DisplayMagician/UIForms/ShortcutForm.cs b/DisplayMagician/UIForms/ShortcutForm.cs index 43506ba..9daa24b 100644 --- a/DisplayMagician/UIForms/ShortcutForm.cs +++ b/DisplayMagician/UIForms/ShortcutForm.cs @@ -14,6 +14,7 @@ using System.Globalization; using Manina.Windows.Forms; using System.Windows.Forms.VisualStyles; using AudioSwitcher.AudioApi.CoreAudio; +using AudioSwitcher.AudioApi; namespace DisplayMagician.UIForms { @@ -44,11 +45,12 @@ namespace DisplayMagician.UIForms private bool _autoName = true; private string _gameId = "0"; private string _uuid = ""; - private CoreAudioController audioController = new CoreAudioController(); + private CoreAudioController audioController = null; private List audioDevices = null; private CoreAudioDevice selectedAudioDevice = null; private List captureDevices = null; private CoreAudioDevice selectedCaptureDevice = null; + private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); public ShortcutForm(ShortcutItem shortcutToEdit) { @@ -56,19 +58,36 @@ namespace DisplayMagician.UIForms // Set the profileAdaptor we need to load images from Profiles // into the Profiles ImageListView - _profileAdaptor = new ProfileAdaptor(); + try + { + _profileAdaptor = new ProfileAdaptor(); - _shortcutToEdit = shortcutToEdit; + _shortcutToEdit = shortcutToEdit; - // Style the Saved Profiles list - ilv_saved_profiles.MultiSelect = false; - ilv_saved_profiles.ThumbnailSize = new Size(100, 100); - ilv_saved_profiles.AllowDrag = false; - ilv_saved_profiles.AllowDrop = false; - ilv_saved_profiles.SetRenderer(new ProfileILVRenderer()); + // Style the Saved Profiles list + ilv_saved_profiles.MultiSelect = false; + ilv_saved_profiles.ThumbnailSize = new Size(100, 100); + ilv_saved_profiles.AllowDrag = false; + ilv_saved_profiles.AllowDrop = false; + ilv_saved_profiles.SetRenderer(new ProfileILVRenderer()); + + } + catch(Exception ex) + { + logger.Error(ex, $"ShortcutForm/ShortcutForm: Exception while trying to setup the game ImageListView and set the render."); + } lbl_profile_shown.Text = "No Display Profiles available"; lbl_profile_shown_subtitle.Text = "Please go back to the main window, click on 'Display Profiles', and save a new Display Profile. Then come back here."; + + try + { + audioController = new CoreAudioController(); + } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutForm/ShortcutForm: Exception while trying to initialise CoreAudioController in ShortcutForm. Audio Chipset on your computer is not supported. You will be unable to set audio settings."); + } } public ShortcutItem Shortcut @@ -283,61 +302,6 @@ namespace DisplayMagician.UIForms } - // Save the Audio features - if (rb_change_audio.Checked) - { - _changeAudioDevice = true; - _audioDevice = cb_audio_device.Text; - } - else - { - _changeAudioDevice = false; - _audioDevice = ""; - } - - - if (rb_set_audio_volume.Checked) - { - _setAudioVolume = true; - _audioVolume = nud_audio_volume.Value; - } - else - { - _setAudioVolume = false; - _audioVolume = -1; - } - - // Save the Capture features - if (rb_change_capture.Checked) - { - _changeCaptureDevice = true; - _captureDevice = cb_capture_device.Text; - } - else - { - _changeCaptureDevice = false; - _captureDevice = ""; - } - - - if (rb_set_capture_volume.Checked) - { - _setCaptureVolume = true; - _captureVolume = nud_capture_volume.Value; - } - else - { - _setCaptureVolume = false; - _captureVolume = -1; - } - - - // Check the audio permanence requirements - if (rb_switch_audio_temp.Checked) - _audioPermanence = ShortcutPermanence.Temporary; - - if (rb_switch_audio_permanent.Checked) - _audioPermanence = ShortcutPermanence.Permanent; // Check the display permanence requirements if (rb_switch_display_temp.Checked) @@ -346,12 +310,116 @@ namespace DisplayMagician.UIForms if (rb_switch_display_permanent.Checked) _displayPermanence = ShortcutPermanence.Permanent; - // Check the microphone permanence requirements - if (rb_switch_capture_temp.Checked) - _capturePermanence = ShortcutPermanence.Temporary; + // If we can get access to the audio chipset then + // we try to get the settings + if (audioController != null) + { + if (audioDevices != null && audioDevices.Count > 0) + { + // Save the Audio features + if (rb_change_audio.Checked) + { + _changeAudioDevice = true; + _audioDevice = cb_audio_device.Text; + } + else + { + _changeAudioDevice = false; + _audioDevice = ""; + } - if (rb_switch_capture_permanent.Checked) - _capturePermanence = ShortcutPermanence.Permanent; + + if (rb_set_audio_volume.Checked) + { + _setAudioVolume = true; + _audioVolume = nud_audio_volume.Value; + } + else + { + _setAudioVolume = false; + _audioVolume = -1; + } + + // Check the audio permanence requirements + if (rb_switch_audio_temp.Checked) + _audioPermanence = ShortcutPermanence.Temporary; + + if (rb_switch_audio_permanent.Checked) + _audioPermanence = ShortcutPermanence.Permanent; + + } + else + { + // No active audio devices found, so we force the save to disable changing the audio device + logger.Warn($"ShortcutForm/btn_save_Click: No active audio devices found, so forcing the save to disable changing the audio device for this shortcut."); + _changeAudioDevice = false; + _audioDevice = ""; + _setAudioVolume = false; + _audioVolume = -1; + _audioPermanence = ShortcutPermanence.Temporary; + } + + if (captureDevices != null && captureDevices.Count > 0) + { + // Save the Capture features + if (rb_change_capture.Checked) + { + _changeCaptureDevice = true; + _captureDevice = cb_capture_device.Text; + } + else + { + _changeCaptureDevice = false; + _captureDevice = ""; + } + + + if (rb_set_capture_volume.Checked) + { + _setCaptureVolume = true; + _captureVolume = nud_capture_volume.Value; + } + else + { + _setCaptureVolume = false; + _captureVolume = -1; + } + + // Check the microphone permanence requirements + if (rb_switch_capture_temp.Checked) + _capturePermanence = ShortcutPermanence.Temporary; + + if (rb_switch_capture_permanent.Checked) + _capturePermanence = ShortcutPermanence.Permanent; + + } + else + { + // No active capture devices found, so we force the save to disable changing the capture device + logger.Warn($"ShortcutForm/btn_save_Click: No active capture devices found, so forcing the save to disable changing the capture device for this shortcut."); + _changeCaptureDevice = false; + _captureDevice = ""; + _setCaptureVolume = false; + _captureVolume = -1; + _capturePermanence = ShortcutPermanence.Temporary; + } + + } + // Otherwise we force set the audio settings to no change + // just to be sure + else + { + _changeAudioDevice = false; + _audioDevice = ""; + _setAudioVolume = false; + _audioVolume = -1; + _changeCaptureDevice = false; + _captureDevice = ""; + _setCaptureVolume = false; + _captureVolume = -1; + _audioPermanence = ShortcutPermanence.Temporary; + _capturePermanence = ShortcutPermanence.Temporary; + } // Save the start program 1 StartProgram myStartProgram = new StartProgram @@ -406,9 +474,11 @@ namespace DisplayMagician.UIForms // If we're launching a game if (rb_launcher.Checked) { + logger.Trace($"ShortcutForm/btn_save_Click: We're saving a game!"); // If the game is a SteamGame - if(txt_game_launcher.Text == SupportedGameLibrary.Steam.ToString()) + if (txt_game_launcher.Text == SupportedGameLibrary.Steam.ToString()) { + logger.Trace($"ShortcutForm/btn_save_Click: We're saving a Steam game!"); // Find the SteamGame _gameToUse = new GameStruct { @@ -443,6 +513,7 @@ namespace DisplayMagician.UIForms // If the game is a UplayGame else if (txt_game_launcher.Text == SupportedGameLibrary.Uplay.ToString()) { + logger.Trace($"ShortcutForm/btn_save_Click: We're saving a Uplay game!"); // Find the UplayGame _gameToUse = new GameStruct { @@ -511,6 +582,7 @@ namespace DisplayMagician.UIForms } else if (rb_standalone.Checked) { + logger.Trace($"ShortcutForm/btn_save_Click: We're saving a standalone executable!"); _executableToUse = new Executable { ExecutableArguments = txt_args_executable.Text, @@ -552,7 +624,7 @@ namespace DisplayMagician.UIForms } else { - + logger.Trace($"ShortcutForm/btn_save_Click: We're not saving any game or executable to start!"); _shortcutToEdit.UpdateNoGameShortcut( txt_shortcut_save_name.Text, _profileToUse, @@ -665,164 +737,212 @@ namespace DisplayMagician.UIForms // Populate all the Audio devices in the audio devices list. // Set the Audio device to the shortcut audio device only if // the Change Audio radiobutton is set - rb_change_audio.Checked = _shortcutToEdit.ChangeAudioDevice; - cb_audio_device.Items.Clear(); - audioDevices = audioController.GetPlaybackDevices().ToList(); - - // If the shortcut is to change the audio device - if (_shortcutToEdit.ChangeAudioDevice) + if (audioController != null) { - // Then we need to populate the list - bool foundAudioDevice = false; - foreach (CoreAudioDevice audioDevice in audioDevices) + rb_change_audio.Checked = _shortcutToEdit.ChangeAudioDevice; + cb_audio_device.Items.Clear(); + + try { - if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Active) + audioDevices = audioController.GetPlaybackDevices(DeviceState.Active).ToList(); + } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutForm/ShortcutForm_Load: Exception while trying to get active playback devices."); + } + + if (audioDevices != null && audioDevices.Count > 0) + { + // If the shortcut is to change the audio device + if (_shortcutToEdit.ChangeAudioDevice) { - int index = cb_audio_device.Items.Add(audioDevice.FullName); - // Set the audio device to the default device by default - if (audioDevice.FullName.Equals(_shortcutToEdit.AudioDevice)) + // Then we need to populate the list + bool foundAudioDevice = false; + foreach (CoreAudioDevice audioDevice in audioDevices) { - foundAudioDevice = true; - selectedAudioDevice = audioDevice; + + int index = cb_audio_device.Items.Add(audioDevice.FullName); + // Set the audio device to the default device by default + if (audioDevice.FullName.Equals(_shortcutToEdit.AudioDevice)) + { + foundAudioDevice = true; + selectedAudioDevice = audioDevice; + cb_audio_device.SelectedIndex = index; + if (_shortcutToEdit.SetAudioVolume && _shortcutToEdit.AudioVolume >= 0 && _shortcutToEdit.AudioVolume <= 100) + { + nud_audio_volume.Value = _shortcutToEdit.AudioVolume; + rb_set_audio_volume.Checked = true; + } + else + { + nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume); + rb_set_audio_volume.Checked = false; + } + } + } + + // We need to handle the edgecase where the selected audio device + // isn't currently plugged in. We don't want to break the shortcut + // as it could be plugged in when it comes time to actually run + // the shortcut, so we need to just add it to the list to not break + // the UI. + + if (!foundAudioDevice) + { + int index = cb_audio_device.Items.Add(_shortcutToEdit.AudioDevice); cb_audio_device.SelectedIndex = index; + selectedAudioDevice = null; if (_shortcutToEdit.SetAudioVolume && _shortcutToEdit.AudioVolume >= 0 && _shortcutToEdit.AudioVolume <= 100) { - nud_audio_volume.Value = _shortcutToEdit.AudioVolume; rb_set_audio_volume.Checked = true; + nud_audio_volume.Value = _shortcutToEdit.AudioVolume; } else { - nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume); - rb_set_audio_volume.Checked = false; + rb_keep_audio_volume.Checked = true; + nud_audio_volume.Value = 50; } } } - } - - // We need to handle the edgecase where the selected audio device - // isn't currently plugged in. We don't want to break the shortcut - // as it could be plugged in when it comes time to actually run - // the shortcut, so we need to just add it to the list to not break - // the UI. - - if (!foundAudioDevice) - { - int index = cb_audio_device.Items.Add(_shortcutToEdit.AudioDevice); - cb_audio_device.SelectedIndex = index; - selectedAudioDevice = null; - if (_shortcutToEdit.SetAudioVolume && _shortcutToEdit.AudioVolume >= 0 && _shortcutToEdit.AudioVolume <= 100) - { - rb_set_audio_volume.Checked = true; - nud_audio_volume.Value = _shortcutToEdit.AudioVolume; - } else { - rb_keep_audio_volume.Checked = true; - nud_audio_volume.Value = 50; - } - } - } - else - { - // Then we need to populate the list - foreach (CoreAudioDevice audioDevice in audioDevices) - { - if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Active) - { - int index = cb_audio_device.Items.Add(audioDevice.FullName); - // Set the audio device to the default device by default - if (audioDevice.IsDefaultDevice) + // Then we need to populate the list + foreach (CoreAudioDevice audioDevice in audioDevices) { - selectedAudioDevice = audioDevice; - cb_audio_device.SelectedIndex = index; - nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume); + int index = cb_audio_device.Items.Add(audioDevice.FullName); + // Set the audio device to the default device by default + if (audioDevice.IsDefaultDevice) + { + selectedAudioDevice = audioDevice; + cb_audio_device.SelectedIndex = index; + nud_audio_volume.Value = Convert.ToDecimal(audioDevice.Volume); + } } + rb_keep_audio_volume.Checked = true; } + } - rb_keep_audio_volume.Checked = true; - } - - - // Populate all the Capture devices in the capture devices list. - // Set the Capture device to the shortcut capture device only if - // the Change Capture radiobutton is set - rb_change_capture.Checked = _shortcutToEdit.ChangeCaptureDevice; - cb_capture_device.Items.Clear(); - captureDevices = audioController.GetCaptureDevices().ToList(); - - // If the shortcut is to change the capture device - if (_shortcutToEdit.ChangeCaptureDevice) - { - // Then we need to populate the list - bool foundCaptureDevice = false; - foreach (CoreAudioDevice captureDevice in captureDevices) + else { - if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active) + // There are no active audio devices found + // so we hide all audio changing controls + gb_audio_settings.Visible = false; + lbl_no_active_audio_devices.Visible = true; + logger.Warn($"ShortcutForm/ShortcutForm_Load: No active playback devices so hiding the audio output controls."); + } + + + // Populate all the Capture devices in the capture devices list. + // Set the Capture device to the shortcut capture device only if + // the Change Capture radiobutton is set + rb_change_capture.Checked = _shortcutToEdit.ChangeCaptureDevice; + cb_capture_device.Items.Clear(); + + try + { + captureDevices = audioController.GetCaptureDevices(DeviceState.Active).ToList(); + } + catch (Exception ex) + { + logger.Warn(ex, $"ShortcutForm/ShortcutForm_Load: Exception while trying to get active capture devices."); + } + + if (captureDevices != null && captureDevices.Count > 0) + { + // If the shortcut is to change the capture device + if (_shortcutToEdit.ChangeCaptureDevice) { - int index = cb_capture_device.Items.Add(captureDevice.FullName); - // Set the capture device to the default device by default - if (captureDevice.FullName.Equals(_shortcutToEdit.CaptureDevice)) + // Then we need to populate the list + bool foundCaptureDevice = false; + foreach (CoreAudioDevice captureDevice in captureDevices) { - foundCaptureDevice = true; - selectedCaptureDevice = captureDevice; + int index = cb_capture_device.Items.Add(captureDevice.FullName); + // Set the capture device to the default device by default + if (captureDevice.FullName.Equals(_shortcutToEdit.CaptureDevice)) + { + foundCaptureDevice = true; + selectedCaptureDevice = captureDevice; + cb_capture_device.SelectedIndex = index; + if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100) + { + nud_capture_volume.Value = _shortcutToEdit.CaptureVolume; + rb_set_capture_volume.Checked = true; + } + else + { + nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume); + rb_set_capture_volume.Checked = false; + } + } + } + + // We need to handle the edgecase where the selected capture device + // isn't currently plugged in. We don't want to break the shortcut + // as it could be plugged in when it comes time to actually run + // the shortcut, so we need to just add it to the list to not break + // the UI. + + if (!foundCaptureDevice) + { + int index = cb_capture_device.Items.Add(_shortcutToEdit.CaptureDevice); cb_capture_device.SelectedIndex = index; + selectedCaptureDevice = null; if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100) { - nud_capture_volume.Value = _shortcutToEdit.CaptureVolume; rb_set_capture_volume.Checked = true; + nud_capture_volume.Value = _shortcutToEdit.CaptureVolume; } else { - nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume); - rb_set_capture_volume.Checked = false; + rb_keep_capture_volume.Checked = true; + nud_capture_volume.Value = 50; } } } - } - - // We need to handle the edgecase where the selected capture device - // isn't currently plugged in. We don't want to break the shortcut - // as it could be plugged in when it comes time to actually run - // the shortcut, so we need to just add it to the list to not break - // the UI. - - if (!foundCaptureDevice) - { - int index = cb_capture_device.Items.Add(_shortcutToEdit.CaptureDevice); - cb_capture_device.SelectedIndex = index; - selectedCaptureDevice = null; - if (_shortcutToEdit.SetCaptureVolume && _shortcutToEdit.CaptureVolume >= 0 && _shortcutToEdit.CaptureVolume <= 100) - { - rb_set_capture_volume.Checked = true; - nud_capture_volume.Value = _shortcutToEdit.CaptureVolume; - } else { + // Then we need to populate the list + foreach (CoreAudioDevice captureDevice in captureDevices) + { + int index = cb_capture_device.Items.Add(captureDevice.FullName); + // Set the capture device to the default device by default + if (captureDevice.IsDefaultDevice) + { + selectedCaptureDevice = captureDevice; + cb_capture_device.SelectedIndex = index; + nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume); + } + } rb_keep_capture_volume.Checked = true; - nud_capture_volume.Value = 50; } + } + else + { + // There are no active audio devices found + // so we hide all audio changing controls + gb_capture_settings.Visible = false; + lbl_no_active_capture_devices.Visible = true; + logger.Warn($"ShortcutForm/ShortcutForm_Load: No active capture devices so hiding the microphone input controls."); + } + } else { - // Then we need to populate the list - foreach (CoreAudioDevice captureDevice in captureDevices) - { - if (captureDevice.State == AudioSwitcher.AudioApi.DeviceState.Active) - { - int index = cb_capture_device.Items.Add(captureDevice.FullName); - // Set the capture device to the default device by default - if (captureDevice.IsDefaultDevice) - { - selectedCaptureDevice = captureDevice; - cb_capture_device.SelectedIndex = index; - nud_capture_volume.Value = Convert.ToDecimal(captureDevice.Volume); - } - } - } - rb_keep_capture_volume.Checked = true; - } + // Audio Controller == null, so the audio device isn't supported by AudioSwitcher.CoreAudio! + // We just have to disable the switching functionality at present :( + // Hopefully I find another library that works with everything including RealTek Audio + gb_audio_settings.Visible = false; + gb_capture_settings.Visible = false; + lbl_disabled_shortcut_audio_chipset.Visible = true; + // We also force the audio settings to off, just in case + rb_change_audio.Checked = false; + rb_set_audio_volume.Checked = false; + rb_change_capture.Checked = false; + rb_set_capture_volume.Checked = false; + } + // Populate a full list of games // Start with the Steam Games diff --git a/DisplayMagician/UIForms/ShortcutLibraryForm.cs b/DisplayMagician/UIForms/ShortcutLibraryForm.cs index e2ffc64..e83804a 100644 --- a/DisplayMagician/UIForms/ShortcutLibraryForm.cs +++ b/DisplayMagician/UIForms/ShortcutLibraryForm.cs @@ -330,6 +330,10 @@ namespace DisplayMagician.UIForms // Create a MaskForm that will cover the ShortcutLibrary Window to lock // the controls and inform the user that the game is running.... MaskedForm maskedForm = MaskedForm.Show(this, message); + maskedForm.BringToFront(); + + ilv_saved_shortcuts.SuspendLayout(); + ilv_saved_shortcuts.Refresh(); // Get the MainForm so we can access the NotifyIcon on it. MainForm mainForm = (MainForm)this.Owner; @@ -337,6 +341,8 @@ namespace DisplayMagician.UIForms // Run the shortcut ShortcutRepository.RunShortcut(_selectedShortcut, mainForm.notifyIcon); + ilv_saved_shortcuts.ResumeLayout(); + maskedForm.Close(); } else diff --git a/DisplayMagicianLogReporter/Properties/AssemblyInfo.cs b/DisplayMagicianLogReporter/Properties/AssemblyInfo.cs index 67be439..211abb2 100644 --- a/DisplayMagicianLogReporter/Properties/AssemblyInfo.cs +++ b/DisplayMagicianLogReporter/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.0")] -[assembly: AssemblyFileVersion("1.0.3.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] \ No newline at end of file diff --git a/DisplayMagicianSetup/Includes/DisplayMagicianVariables.wxi b/DisplayMagicianSetup/Includes/DisplayMagicianVariables.wxi index ac73b2c..7d0e64a 100644 --- a/DisplayMagicianSetup/Includes/DisplayMagicianVariables.wxi +++ b/DisplayMagicianSetup/Includes/DisplayMagicianVariables.wxi @@ -6,10 +6,11 @@ --> - + + - - + + + - - NOT NEWER_VERSION_FOUND + + + + + diff --git a/DisplayMagicianShared/ProfileItem.cs b/DisplayMagicianShared/ProfileItem.cs index 08a0aeb..bea2f81 100644 --- a/DisplayMagicianShared/ProfileItem.cs +++ b/DisplayMagicianShared/ProfileItem.cs @@ -507,10 +507,15 @@ namespace DisplayMagicianShared { // Check each display in this profile and make sure it's currently available int validDisplayCount = 0; + + //validDisplayCount = (from connectedDisplay in ProfileRepository.ConnectedDisplayIdentifiers select connectedDisplay == profileDisplayIdentifier).Count(); + foreach (string profileDisplayIdentifier in ProfileDisplayIdentifiers) { // If this profile has a display that isn't currently available then we need to say it's a no! - if (ProfileRepository.ConnectedDisplayIdentifiers.Contains(profileDisplayIdentifier)) + //if (ProfileRepository.ConnectedDisplayIdentifiers.Contains(profileDisplayIdentifier)) + //validDisplayCount = (from connectedDisplay in ProfileRepository.ConnectedDisplayIdentifiers select connectedDisplay == profileDisplayIdentifier).Count(); + if (ProfileRepository.ConnectedDisplayIdentifiers.Any(s => profileDisplayIdentifier.Equals(s))) validDisplayCount++; } if (validDisplayCount == ProfileDisplayIdentifiers.Count) diff --git a/DisplayMagicianShared/ProfileRepository.cs b/DisplayMagicianShared/ProfileRepository.cs index d40868d..9014e48 100644 --- a/DisplayMagicianShared/ProfileRepository.cs +++ b/DisplayMagicianShared/ProfileRepository.cs @@ -762,8 +762,6 @@ namespace DisplayMagicianShared // Get the list of connected devices ConnectedDisplayIdentifiers = GenerateAllAvailableDisplayIdentifiers(); - - if (_profilesLoaded && _allProfiles.Count > 0) { @@ -794,6 +792,7 @@ namespace DisplayMagicianShared } if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0) + //if (false) { SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected"); @@ -810,8 +809,6 @@ namespace DisplayMagicianShared // Create an array of all the important display info we need to record string[] displayInfo = { "NVIDIA", - myPhysicalGPU.CorrespondingLogicalGPU.ToString(), - myPhysicalGPU.ToString(), myPhysicalGPU.ArchitectInformation.ShortName.ToString(), myPhysicalGPU.ArchitectInformation.Revision.ToString(), myPhysicalGPU.Board.ToString(), @@ -851,46 +848,46 @@ namespace DisplayMagicianShared PathDisplaySource pathDisplaySource = attachedDisplay.ToPathDisplaySource(); PathDisplayTarget pathDisplayTarget = attachedDisplay.ToPathDisplayTarget(); - Debug.WriteLine($"ADDN : {attachedDisplay.DeviceName}"); - Debug.WriteLine($"ADDFN : {attachedDisplay.DisplayFullName}"); - Debug.WriteLine($"ADDIN : {attachedDisplay.DisplayName}"); - Debug.WriteLine($"ADDIN : {attachedDisplay.IsAvailable}"); - Debug.WriteLine($"ADDIGP : {attachedDisplay.IsGDIPrimary}"); - Debug.WriteLine($"ADDIV : {attachedDisplay.IsValid}"); - Debug.WriteLine($"ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); - Debug.WriteLine($"ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); - Debug.WriteLine($"ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); - Debug.WriteLine($"ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); - Debug.WriteLine($"ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); - Debug.WriteLine($"ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); - Debug.WriteLine($"ADCSP : {attachedDisplay.CurrentSetting.Position}"); - Debug.WriteLine($"ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); - Debug.WriteLine($"DP : {displayAdapter.DevicePath}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"DN : {displayAdapter.DeviceName}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"AI : {pathDisplayAdapter.AdapterId}"); - Debug.WriteLine($"AIDP : {pathDisplayAdapter.DevicePath}"); - Debug.WriteLine($"AIII : {pathDisplayAdapter.IsInvalid}"); - Debug.WriteLine($"DDA : {displayAdapter.DeviceName}"); - Debug.WriteLine($"PDSA : {pathDisplaySource.Adapter}"); - Debug.WriteLine($"PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - Debug.WriteLine($"PDSDN : {pathDisplaySource.DisplayName}"); - Debug.WriteLine($"PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - Debug.WriteLine($"PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - Debug.WriteLine($"PDSSI : {pathDisplaySource.SourceId}"); - Debug.WriteLine($"PDTA : {pathDisplayTarget.Adapter}"); - Debug.WriteLine($"PDTCI : {pathDisplayTarget.ConnectorInstance}"); - Debug.WriteLine($"PDTDP : {pathDisplayTarget.DevicePath}"); - Debug.WriteLine($"PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - Debug.WriteLine($"PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - Debug.WriteLine($"PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - Debug.WriteLine($"PDTFN : {pathDisplayTarget.FriendlyName}"); - Debug.WriteLine($"PDTIA : {pathDisplayTarget.IsAvailable}"); - Debug.WriteLine($"PDTPR : {pathDisplayTarget.PreferredResolution}"); - Debug.WriteLine($"PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - Debug.WriteLine($"PDTTI : {pathDisplayTarget.TargetId}"); - Debug.WriteLine($"PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DDA : {displayAdapter.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); // Create an array of all the important display info we need to record string[] displayInfo = { @@ -941,6 +938,7 @@ namespace DisplayMagicianShared } if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0) + //if (false) { SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected"); @@ -958,8 +956,6 @@ namespace DisplayMagicianShared // Create an array of all the important display info we need to record string[] displayInfo = { "NVIDIA", - myPhysicalGPU.CorrespondingLogicalGPU.ToString(), - myPhysicalGPU.ToString(), myPhysicalGPU.ArchitectInformation.ShortName.ToString(), myPhysicalGPU.ArchitectInformation.Revision.ToString(), myPhysicalGPU.Board.ToString(), @@ -1001,46 +997,46 @@ namespace DisplayMagicianShared PathDisplaySource pathDisplaySource = attachedDisplay.ToPathDisplaySource(); PathDisplayTarget pathDisplayTarget = attachedDisplay.ToPathDisplayTarget(); - Debug.WriteLine($"ADDN : {attachedDisplay.DeviceName}"); - Debug.WriteLine($"ADDFN : {attachedDisplay.DisplayFullName}"); - Debug.WriteLine($"ADDIN : {attachedDisplay.DisplayName}"); - Debug.WriteLine($"ADDIN : {attachedDisplay.IsAvailable}"); - Debug.WriteLine($"ADDIGP : {attachedDisplay.IsGDIPrimary}"); - Debug.WriteLine($"ADDIV : {attachedDisplay.IsValid}"); - Debug.WriteLine($"ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); - Debug.WriteLine($"ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); - Debug.WriteLine($"ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); - Debug.WriteLine($"ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); - Debug.WriteLine($"ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); - Debug.WriteLine($"ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); - Debug.WriteLine($"ADCSP : {attachedDisplay.CurrentSetting.Position}"); - Debug.WriteLine($"ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); - Debug.WriteLine($"DP : {displayAdapter.DevicePath}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"DN : {displayAdapter.DeviceName}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"AI : {pathDisplayAdapter.AdapterId}"); - Debug.WriteLine($"AIDP : {pathDisplayAdapter.DevicePath}"); - Debug.WriteLine($"AIII : {pathDisplayAdapter.IsInvalid}"); - Debug.WriteLine($"DDA : {displayAdapter.DeviceName}"); - Debug.WriteLine($"PDSA : {pathDisplaySource.Adapter}"); - Debug.WriteLine($"PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - Debug.WriteLine($"PDSDN : {pathDisplaySource.DisplayName}"); - Debug.WriteLine($"PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - Debug.WriteLine($"PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - Debug.WriteLine($"PDSSI : {pathDisplaySource.SourceId}"); - Debug.WriteLine($"PDTA : {pathDisplayTarget.Adapter}"); - Debug.WriteLine($"PDTCI : {pathDisplayTarget.ConnectorInstance}"); - Debug.WriteLine($"PDTDP : {pathDisplayTarget.DevicePath}"); - Debug.WriteLine($"PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - Debug.WriteLine($"PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - Debug.WriteLine($"PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - Debug.WriteLine($"PDTFN : {pathDisplayTarget.FriendlyName}"); - Debug.WriteLine($"PDTIA : {pathDisplayTarget.IsAvailable}"); - Debug.WriteLine($"PDTPR : {pathDisplayTarget.PreferredResolution}"); - Debug.WriteLine($"PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - Debug.WriteLine($"PDTTI : {pathDisplayTarget.TargetId}"); - Debug.WriteLine($"PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DDA : {displayAdapter.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); // Create an array of all the important display info we need to record string[] displayInfo = { @@ -1069,36 +1065,36 @@ namespace DisplayMagicianShared PathDisplaySource pathDisplaySource = unattachedDisplay.ToPathDisplaySource(); PathDisplayTarget pathDisplayTarget = unattachedDisplay.ToPathDisplayTarget(); - Debug.WriteLine($"ADDN : {unattachedDisplay.DeviceName}"); - Debug.WriteLine($"ADDFN : {unattachedDisplay.DisplayFullName}"); - Debug.WriteLine($"ADDIN : {unattachedDisplay.DisplayName}"); - Debug.WriteLine($"ADDIN : {unattachedDisplay.IsAvailable}"); - Debug.WriteLine($"ADDIV : {unattachedDisplay.IsValid}"); - Debug.WriteLine($"DP : {displayAdapter.DevicePath}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"DN : {displayAdapter.DeviceName}"); - Debug.WriteLine($"DK : {displayAdapter.DeviceKey}"); - Debug.WriteLine($"AI : {pathDisplayAdapter.AdapterId}"); - Debug.WriteLine($"AIDP : {pathDisplayAdapter.DevicePath}"); - Debug.WriteLine($"AIII : {pathDisplayAdapter.IsInvalid}"); - Debug.WriteLine($"PDSA : {pathDisplaySource.Adapter}"); - Debug.WriteLine($"PDSCDS : {pathDisplaySource.CurrentDPIScale}"); - Debug.WriteLine($"PDSDN : {pathDisplaySource.DisplayName}"); - Debug.WriteLine($"PDSMDS : {pathDisplaySource.MaximumDPIScale}"); - Debug.WriteLine($"PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); - Debug.WriteLine($"PDSSI : {pathDisplaySource.SourceId}"); - Debug.WriteLine($"PDTA : {pathDisplayTarget.Adapter}"); - Debug.WriteLine($"PDTCI : {pathDisplayTarget.ConnectorInstance}"); - Debug.WriteLine($"PDTDP : {pathDisplayTarget.DevicePath}"); - Debug.WriteLine($"PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); - Debug.WriteLine($"PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); - Debug.WriteLine($"PDTEPC : {pathDisplayTarget.EDIDProductCode}"); - Debug.WriteLine($"PDTFN : {pathDisplayTarget.FriendlyName}"); - Debug.WriteLine($"PDTIA : {pathDisplayTarget.IsAvailable}"); - Debug.WriteLine($"PDTPR : {pathDisplayTarget.PreferredResolution}"); - Debug.WriteLine($"PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); - Debug.WriteLine($"PDTTI : {pathDisplayTarget.TargetId}"); - Debug.WriteLine($"PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {unattachedDisplay.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {unattachedDisplay.DisplayFullName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {unattachedDisplay.IsValid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}"); + SharedLogger.logger.Trace($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}"); // Create an array of all the important display info we need to record string[] displayInfo = { diff --git a/DisplayMagicianShared/Properties/AssemblyInfo.cs b/DisplayMagicianShared/Properties/AssemblyInfo.cs index 9581cc4..bf1d4e1 100644 --- a/DisplayMagicianShared/Properties/AssemblyInfo.cs +++ b/DisplayMagicianShared/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.*")] -[assembly: AssemblyFileVersion("1.0.3.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] \ No newline at end of file diff --git a/DisplayMagicianShellExtension/Properties/AssemblyInfo.cs b/DisplayMagicianShellExtension/Properties/AssemblyInfo.cs index 22aaad8..2ce5e0a 100644 --- a/DisplayMagicianShellExtension/Properties/AssemblyInfo.cs +++ b/DisplayMagicianShellExtension/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.*")] -[assembly: AssemblyFileVersion("1.0.3.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.4.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] \ No newline at end of file diff --git a/docs/update/index.json b/docs/update/index.json index ca23ed1..e6a1148 100644 --- a/docs/update/index.json +++ b/docs/update/index.json @@ -1,6 +1,6 @@ { - "version": "1.0.3.0", - "url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.3/DisplayMagicianSetup-v1.0.3.msi", + "version": "1.0.4.0", + "url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.4/DisplayMagicianSetup-v1.0.4.msi", "changelog": "https://github.com/terrymacdonald/DisplayMagician/releases", "mandatory": { "value": false, @@ -8,7 +8,7 @@ "mode": 0 }, "checksum": { - "value": "F2D3584C6F345F4B7F61260356DE92D4B4F3EA6FDF5EE4CD84CF37CAB0F6E7F9", + "value": "253E7B3BCC753AA7621BD88C7F86155B5CAF5C09C2DD222B25A3D4F3D819790E", "hashingAlgorithm": "SHA256" } }