Merge branch 'release/1.0.4' into main

This commit is contained in:
Terry MacDonald 2021-04-10 22:23:37 +12:00
commit 867d218c3e
21 changed files with 1535 additions and 784 deletions

View File

@ -107,6 +107,7 @@
<Compile Include="IconFromFile.cs" />
<Compile Include="IconUtils.cs" />
<Compile Include="ImageUtils.cs" />
<Compile Include="ProcessCommandLine.cs" />
<Compile Include="ProgramSettings.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>

View File

@ -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;
}
}

View File

@ -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<=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(steamGameNameOrUuid))
return false;
logger.Debug($"SteamLibrary/RemoveSteamGame3: Removing Steam game with Name or UUID {steamGameNameOrUuid} from the Steam library");
int numRemoved;
Match match = Regex.Match(steamGameNameOrUuid, steamAppIdRegex, RegexOptions.IgnoreCase);
if (match.Success)
@ -216,9 +240,15 @@ namespace DisplayMagician.GameLibraries
numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrUuid.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<int> steamAppIdsInstalled = new List<int>();
// Now look for what games app id's are actually installed on this computer
@ -355,11 +374,14 @@ namespace DisplayMagician.GameLibraries
{
if (steamAppsKey != null)
{
//
// Loop through the subKeys as they are the Steam Game IDs
foreach (string steamGameKeyName in steamAppsKey.GetSubKeyNames())
{
logger.Trace($"SteamLibrary/LoadInstalledGames: Found SteamGameKeyName = {steamGameKeyName}");
if (int.TryParse(steamGameKeyName, out int steamAppId))
{
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))
{
@ -367,14 +389,33 @@ namespace DisplayMagician.GameLibraries
// 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;
}
}
@ -389,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)
@ -408,31 +449,35 @@ namespace DisplayMagician.GameLibraries
GameID = detectedAppID,
GameExes = new List<string>()
};
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}");
}
}
}
@ -444,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")
@ -455,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());
}
@ -466,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<string> steamLibrariesPaths = new List<string>();
// 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);
@ -498,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);
}
}
@ -512,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
@ -519,12 +578,13 @@ namespace DisplayMagician.GameLibraries
Match appidMatches = appidRegex.Match(steamLibraryAppManifestText);
if (appidMatches.Success)
{
if (int.TryParse(appidMatches.Groups[1].Value, out int steamGameId))
{
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 = "";
@ -533,6 +593,8 @@ namespace DisplayMagician.GameLibraries
// Construct the full path to the game dir from the appInfo and libraryAppManifest data
string steamGameInstallDir = Path.Combine(steamLibraryPath, @"steamapps", @"common", steamAppInfo[steamGameId].GameInstallDir);
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)
@ -540,9 +602,11 @@ namespace DisplayMagician.GameLibraries
foreach (string gameExe in steamAppInfo[steamGameId].GameExes)
{
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;
}
}
@ -555,57 +619,60 @@ namespace DisplayMagician.GameLibraries
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}");
}
}
}
}
}
}
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;

View File

@ -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

View File

@ -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<string> uplayConfigFile = uplayConfigFileString.Split(dividingText,StringSplitOptions.RemoveEmptyEntries).ToList();
// Split the file into records at the SOH unicode character
List<string> uplayConfigFile = uplayConfigFileString.Split((Char)1).ToList();
//List<string> 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,38 +464,6 @@ namespace DisplayMagician.GameLibraries
// for each game record grab:
UplayAppInfo uplayGameAppInfo = new UplayAppInfo();
/* // name: (lookup the id in lookup table to find the name if needed)
if (uplayEntryLines.Exists(a => a.StartsWith(" name:", StringComparison.InvariantCultureIgnoreCase)))
{
mc = Regex.Matches(uplayEntry, @" name\: (.*)");
uplayGameAppInfo.GameName = mc[0].Groups[1].ToString();
// if the name contains a localization reference, then dereference it
if (localizations.ContainsKey(uplayGameAppInfo.GameName))
{
uplayGameAppInfo.GameName = localizations[uplayGameAppInfo.GameName];
}
}
else
continue;
*/
// icon_image: (lookup the id in lookup table to find the ICON)
/*if (uplayEntryLines.Exists(a => a.StartsWith(" icon_image:", StringComparison.InvariantCultureIgnoreCase)))
{
mc = Regex.Matches(uplayEntry, @"icon_image: (.*)");
string iconImageFileName = mc[0].Groups[1].ToString();
// if the icon_image contains a localization reference, then dereference it
if (localizations.ContainsKey(iconImageFileName))
{
iconImageFileName = localizations[iconImageFileName];
}
//61fdd16f06ae08158d0a6d476f1c6bd5.ico
string uplayGameIconPath = _uplayPath + @"data\games\" + iconImageFileName;
if (File.Exists(uplayGameIconPath) && uplayGameIconPath.EndsWith(".ico"))
{
uplayGameAppInfo.GameUplayIconPath = uplayGameIconPath;
}
}*/
// 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)
@ -447,11 +478,17 @@ namespace DisplayMagician.GameLibraries
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)
{
@ -462,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)
@ -472,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;
}
@ -487,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)
@ -495,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 = int.Parse(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;

View File

@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
namespace DisplayMagician
{
public static class ProcessCommandLine
{
private static class Win32Native
{
public const uint PROCESS_BASIC_INFORMATION = 0;
[Flags]
public enum OpenProcessDesiredAccessFlags : uint
{
PROCESS_VM_READ = 0x0010,
PROCESS_QUERY_INFORMATION = 0x0400,
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessBasicInformation
{
public IntPtr Reserved1;
public IntPtr PebBaseAddress;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] Reserved2;
public IntPtr UniqueProcessId;
public IntPtr Reserved3;
}
[StructLayout(LayoutKind.Sequential)]
public struct UnicodeString
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
// This is not the real struct!
// I faked it to get ProcessParameters address.
// Actual struct definition:
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb
[StructLayout(LayoutKind.Sequential)]
public struct PEB
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] Reserved;
public IntPtr ProcessParameters;
}
[StructLayout(LayoutKind.Sequential)]
public struct RtlUserProcessParameters
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public IntPtr[] Reserved2;
public UnicodeString ImagePathName;
public UnicodeString CommandLine;
}
[DllImport("ntdll.dll")]
public static extern uint NtQueryInformationProcess(
IntPtr ProcessHandle,
uint ProcessInformationClass,
IntPtr ProcessInformation,
uint ProcessInformationLength,
out uint ReturnLength);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
OpenProcessDesiredAccessFlags dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
uint dwProcessId);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer,
uint nSize, out uint lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("shell32.dll", SetLastError = true,
CharSet = CharSet.Unicode, EntryPoint = "CommandLineToArgvW")]
public static extern IntPtr CommandLineToArgv(string lpCmdLine, out int pNumArgs);
}
private static bool ReadStructFromProcessMemory<TStruct>(
IntPtr hProcess, IntPtr lpBaseAddress, out TStruct val)
{
val = default;
var structSize = Marshal.SizeOf<TStruct>();
var mem = Marshal.AllocHGlobal(structSize);
try
{
if (Win32Native.ReadProcessMemory(
hProcess, lpBaseAddress, mem, (uint)structSize, out var len) &&
(len == structSize))
{
val = Marshal.PtrToStructure<TStruct>(mem);
return true;
}
}
finally
{
Marshal.FreeHGlobal(mem);
}
return false;
}
public static string ErrorToString(int error) =>
new string[]
{
"Success",
"Failed to open process for reading",
"Failed to query process information",
"PEB address was null",
"Failed to read PEB information",
"Failed to read process parameters",
"Failed to read command line from process"
}[Math.Abs(error)];
public static int Retrieve(Process process, out string commandLine)
{
int rc = 0;
commandLine = null;
var hProcess = Win32Native.OpenProcess(
Win32Native.OpenProcessDesiredAccessFlags.PROCESS_QUERY_INFORMATION |
Win32Native.OpenProcessDesiredAccessFlags.PROCESS_VM_READ, false, (uint)process.Id);
if (hProcess != IntPtr.Zero)
{
try
{
var sizePBI = Marshal.SizeOf<Win32Native.ProcessBasicInformation>();
var memPBI = Marshal.AllocHGlobal(sizePBI);
try
{
var ret = Win32Native.NtQueryInformationProcess(
hProcess, Win32Native.PROCESS_BASIC_INFORMATION, memPBI,
(uint)sizePBI, out var len);
if (0 == ret)
{
var pbiInfo = Marshal.PtrToStructure<Win32Native.ProcessBasicInformation>(memPBI);
if (pbiInfo.PebBaseAddress != IntPtr.Zero)
{
if (ReadStructFromProcessMemory<Win32Native.PEB>(hProcess,
pbiInfo.PebBaseAddress, out var pebInfo))
{
if (ReadStructFromProcessMemory<Win32Native.RtlUserProcessParameters>(
hProcess, pebInfo.ProcessParameters, out var ruppInfo))
{
var clLen = ruppInfo.CommandLine.MaximumLength;
var memCL = Marshal.AllocHGlobal(clLen);
try
{
if (Win32Native.ReadProcessMemory(hProcess,
ruppInfo.CommandLine.Buffer, memCL, clLen, out len))
{
commandLine = Marshal.PtrToStringUni(memCL);
rc = 0;
}
else
{
// couldn't read command line buffer
rc = -6;
}
}
finally
{
Marshal.FreeHGlobal(memCL);
}
}
else
{
// couldn't read ProcessParameters
rc = -5;
}
}
else
{
// couldn't read PEB information
rc = -4;
}
}
else
{
// PebBaseAddress is null
rc = -3;
}
}
else
{
// NtQueryInformationProcess failed
rc = -2;
}
}
finally
{
Marshal.FreeHGlobal(memPBI);
}
}
finally
{
Win32Native.CloseHandle(hProcess);
}
}
else
{
// couldn't open process for VM read
rc = -1;
}
return rc;
}
public static IReadOnlyList<string> CommandLineToArgs(string commandLine)
{
if (string.IsNullOrEmpty(commandLine)) { return Array.Empty<string>(); }
var argv = Win32Native.CommandLineToArgv(commandLine, out var argc);
if (argv == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
var args = new string[argc];
for (var i = 0; i < args.Length; ++i)
{
var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
args[i] = Marshal.PtrToStringUni(p);
}
return args.ToList().AsReadOnly();
}
finally
{
Marshal.FreeHGlobal(argv);
}
}
}
}

View File

@ -157,6 +157,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++)
@ -686,7 +722,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})");
@ -710,7 +745,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})");

View File

@ -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)]

View File

@ -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<CoreAudioDevice> audioDevices = audioController.GetPlaybackDevices();
foreach (CoreAudioDevice audioDevice in audioDevices)
IEnumerable<CoreAudioDevice> 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<CoreAudioDevice> captureDevices = audioController.GetCaptureDevices();
foreach (CoreAudioDevice captureDevice in captureDevices)
IEnumerable<CoreAudioDevice> 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

View File

@ -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<CoreAudioDevice> 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<CoreAudioDevice> activeAudioDevices = new List<CoreAudioDevice>();
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<CoreAudioDevice> activeCaptureDevices = new List<CoreAudioDevice>();
IEnumerable<CoreAudioDevice> 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<Process> processesToMonitor = new List<Process>();
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<Process> 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)
@ -1369,43 +1427,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
@ -1429,6 +1509,10 @@ namespace DisplayMagician
}
}
else
{
logger.Debug($"ShortcutRepository/RunShortcut: Shortcut did not require changing Display Profile, so no need to change it back.");
}
}

View File

@ -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;
}
}

View File

@ -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 int _gameId = 0;
private string _uuid = "";
private CoreAudioController audioController = new CoreAudioController();
private CoreAudioController audioController = null;
private List<CoreAudioDevice> audioDevices = null;
private CoreAudioDevice selectedAudioDevice = null;
private List<CoreAudioDevice> 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 SteamGame
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
{
@ -477,6 +548,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,
@ -518,7 +590,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,
@ -631,164 +703,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

View File

@ -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

View File

@ -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")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]

View File

@ -6,10 +6,11 @@
-->
<?define MajorVersion="1" ?>
<?define MinorVersion="0" ?>
<?define BuildVersion="3" ?>
<?define BuildVersion="4" ?>
<!-- Revision is NOT used by WiX in the upgrade procedure -->
<!-- Full version number to display -->
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>
<!--
Upgrade code HAS to be the same for all updates.
Once you've chosen it don't change it.

View File

@ -15,12 +15,20 @@
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<!-- Upgrade settings. This will be explained in more detail in a future post -->
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.VersionNumber)" IncludeMinimum="no" Property="NEWER_VERSION_FOUND" />
<UpgradeVersion Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="$(var.VersionNumber)" IncludeMaximum="no" Property="OLDER_VERSION_FOUND" IgnoreRemoveFailure="yes" />
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.VersionNumber)" IncludeMinimum="no" Property="NEWERFOUND" />
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.VersionNumber)" Maximum="$(var.VersionNumber)" IncludeMinimum="yes" IncludeMaximum="yes" Property="SELFFOUND" />
<UpgradeVersion Minimum="0.0.0.0" IncludeMinimum="no" Maximum="$(var.VersionNumber)" IncludeMaximum="no" Property="OLDER_VERSION_FOUND" IgnoreRemoveFailure="yes" />
</Upgrade>
<Condition Message="A newer version of [ProductName] is already installed.">
NOT NEWER_VERSION_FOUND
<CustomAction Id='AlreadyUpdated' Error='!(loc.ProductName) has already been updated to $(var.VersionNumber) or newer. If you want to reinstall this version then uninstall !(loc.ProductName) first.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />
<!--<Condition Message="A newer version of [ProductName] is already installed.">
NEWER_FOUND
</Condition>
<Condition Message="You are trying to upgrade to the same version of [ProductName].">
SELF_FOUND
</Condition>-->
<!--<MajorUpgrade IgnoreRemoveFailure="yes" AllowDowngrades="no" AllowSameVersionUpgrades="no" DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />-->
<!-- Reference the global WIXNETFX4RELEASEINSTALLED property so that will automatically pull in the .Net 4.8 variables (WiX 3.14 and higher only supported) -->
<!--<PropertyRef Id="WIX_IS_NETFRAMEWORK_48_OR_LATER_INSTALLED"/>
@ -143,6 +151,8 @@
<RemoveExistingProducts After="InstallInitialize"/>
<Custom Action="InstallShell" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallShell" Before="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
</InstallExecuteSequence>
<!-- Set the components defined in our fragment files that will be used for our feature -->

View File

@ -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)

View File

@ -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 = {

View File

@ -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")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]

View File

@ -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")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]

View File

@ -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"
}
}