mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Merged in hotfix for 1.0.6
This commit is contained in:
commit
43374ff1b2
@ -40,6 +40,8 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
public virtual bool IsRunning { get; set; }
|
||||
|
||||
public virtual bool IsUpdating { get; set; }
|
||||
|
||||
public virtual List<string> GameLibraryProcesses { get; set; }
|
||||
#endregion
|
||||
|
||||
|
@ -120,40 +120,13 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
// Have to do much more research to figure out how to detect when Origin is updating a game
|
||||
/*public override bool IsUpdating
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
using (
|
||||
var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
if ((int)key?.GetValue(@"Updating", 0) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
Console.WriteLine($"OriginGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
Console.WriteLine($"OriginGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public override GameStartMode StartMode
|
||||
{
|
||||
|
@ -170,6 +170,18 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
// Not implemeted at present
|
||||
// so we just return a false
|
||||
// TODO Implement Origin specific detection for updating the game client
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
@ -416,17 +428,21 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
var localContentPath = Path.Combine(_originLocalContent, "LocalContent");
|
||||
//var games = new Dictionary<string, GameInfo>();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Looking for Local Content in {localContentPath}");
|
||||
|
||||
if (Directory.Exists(localContentPath))
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Local Content Directory {localContentPath} exists!");
|
||||
string[] packages = Directory.GetFiles(localContentPath, "*.mfst", SearchOption.AllDirectories);
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Found .mfst files in Local Content Directory {localContentPath}: {packages.ToString()}");
|
||||
foreach (string package in packages)
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Parsing {package} name to find GameID");
|
||||
try
|
||||
{
|
||||
GameAppInfo originGame = new GameAppInfo();
|
||||
originGame.GameID = Path.GetFileNameWithoutExtension(package);
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Got GameID of {originGame.GameID } from file {package}");
|
||||
if (!originGame.GameID.StartsWith("Origin"))
|
||||
{
|
||||
// If the gameId doesn't start with origin, then we need to find it!
|
||||
@ -435,70 +451,101 @@ namespace DisplayMagician.GameLibraries
|
||||
Match match = Regex.Match(originGame.GameID, @"^(.*?)(\d+)$");
|
||||
if (!match.Success)
|
||||
{
|
||||
logger.Warn("Failed to get game id from file " + package);
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Failed to match game id from file {package} name so ignoring game");
|
||||
continue;
|
||||
}
|
||||
|
||||
originGame.GameID = match.Groups[1].Value + ":" + match.Groups[2].Value;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: GameID doesn't start with 'Origin' so using different pattern to find {originGame.GameID} GameID");
|
||||
}
|
||||
|
||||
// Now we get the rest of the game information out of the manifest file
|
||||
Dictionary<string, string> manifestInfo = ParseOriginManifest(package);
|
||||
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Looking whether Origin is still downloading the game to install it");
|
||||
if (manifestInfo.ContainsKey("ddinitialdownload") && manifestInfo["ddinitialdownload"] == "1")
|
||||
{
|
||||
// Origin is downloading and installing the game so we skip it
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin is still downloading the game with Game ID {originGame.GameID} to install it");
|
||||
continue;
|
||||
}
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Looking whether Origin is downloading game updates");
|
||||
if (manifestInfo.ContainsKey("downloading") && manifestInfo["downloading"] == "1")
|
||||
{
|
||||
// Origin is downloading some new content so we can't play it at the moment
|
||||
// but we can still configure it
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin is downloading game updates for the game with Game ID {originGame.GameID}");
|
||||
continue;
|
||||
}
|
||||
|
||||
originGame.GameInstallDir = null;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Looking where the game with Game ID {originGame.GameID} is installed");
|
||||
if (manifestInfo.ContainsKey("dipinstallpath"))
|
||||
{
|
||||
// This is where Origin has installed this game
|
||||
originGame.GameInstallDir = HttpUtility.UrlDecode(manifestInfo["dipinstallpath"]);
|
||||
if (!Directory.Exists(originGame.GameInstallDir))
|
||||
if (String.IsNullOrEmpty(originGame.GameInstallDir) || !Directory.Exists(originGame.GameInstallDir))
|
||||
{
|
||||
logger.Debug($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no valid directory found at {originGame.GameInstallDir}");
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no valid directory found at {originGame.GameInstallDir}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now we want to look in the dinstallpath location for the game info
|
||||
// for the __Installer\installerdata.xml
|
||||
else
|
||||
{
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Couldn't figure out where Game ID {originGame.GameID} is installed. Skipping game.");
|
||||
}
|
||||
|
||||
string gameInstallerData = Path.Combine(originGame.GameInstallDir, @"__Installer", @"installerdata.xml");
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Parsing the Game Installer Data at {gameInstallerData}");
|
||||
|
||||
if (File.Exists(gameInstallerData))
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Game Installer Data file was found at {gameInstallerData}");
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Attempting to parse XML Game Installer Data file at {gameInstallerData}");
|
||||
// Now we parse the XML
|
||||
XDocument xdoc = XDocument.Load(gameInstallerData);
|
||||
originGame.GameName = xdoc.XPathSelectElement("/DiPManifest/gameTitles/gameTitle[@locale='en_US']").Value;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Game Name {originGame.GameName} found in Game Installer Data file {gameInstallerData}");
|
||||
string gameFilePath = xdoc.XPathSelectElement("/DiPManifest/runtime/launcher/filePath").Value;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Game File Path is {gameFilePath } found in Game Installer Data file {gameInstallerData}");
|
||||
|
||||
string originGameInstallLocation = "";
|
||||
// Check whether gameFilePath contains a registry key! Cause if it does we need to lookup the path there instead
|
||||
if (gameFilePath.StartsWith("[HKEY_LOCAL_MACHINE"))
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Game File Path starts with a registery key so needs to be translated");
|
||||
// The filePath contains a registry key lookup that we need to execute and replace
|
||||
string originGameInstallKeyNameAndValue = "";
|
||||
string originGameRestOfFile = "";
|
||||
MatchCollection mc = Regex.Matches(gameFilePath, @"\[HKEY_LOCAL_MACHINE\\(.*)\](.*)");
|
||||
string originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
||||
string originGameRestOfFile = mc[0].Groups[2].ToString();
|
||||
if (originGameInstallKeyNameAndValue == null)
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
// Split the Reg key bit from the File Path bit
|
||||
|
||||
originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: originGameInstallKeyNameAndValue = {originGameInstallKeyNameAndValue}");
|
||||
originGameRestOfFile = mc[0].Groups[2].ToString();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: originGameRestOfFile = {originGameRestOfFile}");
|
||||
if (originGameInstallKeyNameAndValue == null || originGameInstallKeyNameAndValue == "")
|
||||
{
|
||||
// then we have a problem and we need to continue and ignore this game
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has registry but we can't match it! gameFilePath is {gameFilePath}.");
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has registry key but we can't extract it! gameFilePath is {gameFilePath}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
||||
string originGameInstallKeyName = mc[0].Groups[1].ToString();
|
||||
string originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
||||
// Split the reg key from the value name
|
||||
|
||||
string originGameInstallKeyName = "";
|
||||
string originGameInstallKeyValue = "";
|
||||
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
originGameInstallKeyName = mc[0].Groups[1].ToString();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: originGameInstallKeyName = {originGameInstallKeyName }");
|
||||
originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: originGameInstallKeyValue = {originGameInstallKeyValue }");
|
||||
}
|
||||
|
||||
// Lookup the reg key to figure out where the game is installed
|
||||
try
|
||||
{
|
||||
RegistryKey originGameInstallKey = Registry.LocalMachine.OpenSubKey(originGameInstallKeyName, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
@ -508,8 +555,7 @@ namespace DisplayMagician.GameLibraries
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has a install reg key we cannot find! originGameInstallKey is {gameFilePath} and originGameInstallKeyValue is {originGameInstallKeyValue}.");
|
||||
continue;
|
||||
}
|
||||
string originGameInstallLocation = originGameInstallKey.GetValue(originGameInstallKeyValue).ToString();
|
||||
originGameInstallLocation = Path.Combine(originGameInstallLocation, originGameRestOfFile);
|
||||
originGameInstallLocation = Path.Combine(originGameInstallKey.GetValue(originGameInstallKeyValue).ToString(), originGameRestOfFile);
|
||||
if (!File.Exists(originGameInstallLocation))
|
||||
{
|
||||
// then we have a problem as we cannot locate the game exe file to start!
|
||||
@ -517,29 +563,41 @@ namespace DisplayMagician.GameLibraries
|
||||
continue;
|
||||
}
|
||||
originGame.GameExePath = originGameInstallLocation;
|
||||
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {}.");
|
||||
logger.Warn(ex, $"OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {originGameInstallKeyName}, so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed), so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check, so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed, so skipping game");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Game File Path {gameFilePath} starts with '[HEKY_LOCAL_MACHINE' but didn't match the regex when it should have");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
else if (gameFilePath.StartsWith("[HKEY_CURRENT_USER"))
|
||||
{
|
||||
// The filePath contains a registry key lookup that we need to execute and replace
|
||||
MatchCollection mc = Regex.Matches(gameFilePath, @"\[HKEY_CURRENT_USER\\(.*)\](.*)");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
string originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
||||
string originGameRestOfFile = mc[0].Groups[2].ToString();
|
||||
if (originGameInstallKeyNameAndValue == null)
|
||||
@ -562,8 +620,7 @@ namespace DisplayMagician.GameLibraries
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has a install reg key we cannot find! originGameInstallKey is {gameFilePath} and originGameInstallKeyValue is {originGameInstallKeyValue}.");
|
||||
continue;
|
||||
}
|
||||
string originGameInstallLocation = originGameInstallKey.GetValue(originGameInstallKeyValue).ToString();
|
||||
originGameInstallLocation = Path.Combine(originGameInstallLocation, originGameRestOfFile);
|
||||
originGameInstallLocation = Path.Combine(originGameInstallKey.GetValue(originGameInstallKeyValue).ToString(), originGameRestOfFile);
|
||||
if (!File.Exists(originGameInstallLocation))
|
||||
{
|
||||
// then we have a problem as we cannot locate the game exe file to start!
|
||||
@ -575,39 +632,56 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {}.");
|
||||
logger.Warn(ex, $"OriginLibrary/LoadInstalledGames: The user does not have the permissions required to read the Origin Game location registry key {originGameInstallKeyName}, so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed), so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check, so skipping game");
|
||||
continue;
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed, so skipping game");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Game File Path {gameFilePath} starts with '[HKEY_CURRENT_USER' but didn't match the regex when it should have, so skipping game");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we get here, then the gameFilepath is the actual filepath! So we just copy it.
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Game File Path {gameFilePath} doesn't start with '[HKEY_LOCAL_MACHINE' or '[HKEY_CURRENT_USER' so it must be aplain file path");
|
||||
originGame.GameExePath = gameFilePath;
|
||||
}
|
||||
|
||||
|
||||
if (!File.Exists(originGame.GameExePath))
|
||||
{
|
||||
logger.Debug($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no game exe found at {originGame.GameExePath}");
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no game exe found at originGame.GameExePath {originGame.GameExePath} so skipping game");
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO check for icon! For now we will just use the exe one
|
||||
originGame.GameIconPath = originGame.GameExePath;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Origin gameIconPath = {originGame.GameIconPath} (currently just taking it from the file exe!");
|
||||
|
||||
// If we reach here we add the Game to the list of games we have!
|
||||
_allOriginGames.Add(new OriginGame(originGame.GameID, originGame.GameName, originGame.GameExePath, originGame.GameIconPath));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we can't find the __Installer\installerdata.xml file then we ignore this game
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Couldn't find Game Installer Data file at {gameInstallerData} for game with GameID {originGame.GameID} so skipping this game");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -625,55 +699,6 @@ namespace DisplayMagician.GameLibraries
|
||||
return false;
|
||||
}
|
||||
|
||||
// up to here
|
||||
|
||||
|
||||
|
||||
/* 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 OriginGameInstallKey = Registry.LocalMachine.OpenSubKey(gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
// If the key doesn't exist we skip it as the game isn't installed any longer!
|
||||
if (OriginGameInstallKey == null)
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: Skipping Origin Game {OriginGameAppInfo.GameName} as it isn't installed at the moment (it was uninstalled at some point)");
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we get here, then we have a real game.
|
||||
foreach (string regKeyName in OriginGameInstallKey.GetValueNames())
|
||||
{
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameInstallKey[{regKeyName}] = {OriginGameInstallKey.GetValue(regKeyName)}");
|
||||
}
|
||||
|
||||
// From that we lookup the actual game path
|
||||
string gameInstallDir = OriginGameInstallKey.GetValue("InstallDir", "").ToString();
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: gameInstallDir found = {gameInstallDir}");
|
||||
if (!String.IsNullOrWhiteSpace(gameInstallDir))
|
||||
{
|
||||
OriginGameAppInfo.GameInstallDir = Path.GetFullPath(gameInstallDir).TrimEnd('\\');
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameInstallDir = {OriginGameAppInfo.GameInstallDir }");
|
||||
OriginGameAppInfo.GameExe = Path.Combine(OriginGameAppInfo.GameInstallDir, gameFileName);
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameExe = {OriginGameAppInfo.GameExePath }");
|
||||
OriginGameAppInfo.GameID = gameId;
|
||||
logger.Trace($"OriginLibrary/LoadInstalledGames: OriginGameAppInfo.GameID = {OriginGameAppInfo.GameID }");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"OriginLibrary/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!
|
||||
_allOriginGames.Add(new OriginGame(OriginGameAppInfo.GameID, OriginGameAppInfo.GameName, OriginGameAppInfo.GameExePath, OriginGameAppInfo.GameOriginIconPath));
|
||||
logger.Debug($"OriginLibrary/LoadInstalledGames: Adding Origin Game with game id {OriginGameAppInfo.GameID}, name {OriginGameAppInfo.GameName}, game exe {OriginGameAppInfo.GameExePath} and icon path {OriginGameAppInfo.GameOriginIconPath}");
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
logger.Info($"OriginLibrary/LoadInstalledGames: Found {_allOriginGames.Count} installed Origin games");
|
||||
|
||||
}
|
||||
|
@ -188,6 +188,18 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
// Not implemeted at present
|
||||
// so we just return a false
|
||||
// TODO Implement Origin specific detection for updating the game client
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
|
@ -120,40 +120,13 @@ 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
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
using (
|
||||
var key = Registry.CurrentUser.OpenSubKey(_gameRegistryKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
if ((int)key?.GetValue(@"Updating", 0) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
Console.WriteLine($"UplayGame/IsUpdating securityexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("SecurityException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// Extract some information from this exception, and then
|
||||
// throw it to the parent method.
|
||||
Console.WriteLine($"UplayGame/IsUpdating ioexception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||
if (ex.Source != null)
|
||||
Console.WriteLine("IOException source: {0} - Message: {1}", ex.Source, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public override GameStartMode StartMode
|
||||
{
|
||||
|
@ -165,6 +165,18 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override bool IsUpdating
|
||||
{
|
||||
get
|
||||
{
|
||||
// Not implemeted at present
|
||||
// so we just return a false
|
||||
// TODO Implement Uplay specific detection for updating the game client
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
@ -547,6 +559,8 @@ namespace DisplayMagician.GameLibraries
|
||||
if (uplayEntryLines[i].StartsWith(" name:", StringComparison.OrdinalIgnoreCase) && !gotGameName)
|
||||
{
|
||||
mc = Regex.Matches(uplayEntryLines[i], @" name\: (.*)");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
uplayGameAppInfo.GameName = mc[0].Groups[1].ToString();
|
||||
// if the name contains a localization reference, then dereference it
|
||||
if (localizations.ContainsKey(uplayGameAppInfo.GameName))
|
||||
@ -556,9 +570,12 @@ namespace DisplayMagician.GameLibraries
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: Found uplayGameAppInfo.GameName = {uplayGameAppInfo.GameName}");
|
||||
gotGameName = true;
|
||||
}
|
||||
}
|
||||
else if (uplayEntryLines[i].StartsWith(" icon_image:", StringComparison.OrdinalIgnoreCase) && !gotGameIconPath)
|
||||
{
|
||||
mc = Regex.Matches(uplayEntryLines[i], @"icon_image: (.*)");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
string iconImageFileName = mc[0].Groups[1].ToString();
|
||||
// if the icon_image contains a localization reference, then dereference it
|
||||
if (localizations.ContainsKey(iconImageFileName))
|
||||
@ -575,26 +592,39 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
gotGameIconPath = true;
|
||||
}
|
||||
}
|
||||
// This line contains the filename
|
||||
else if (uplayEntryLines[i].StartsWith(" relative:") && !gotGameFileName)
|
||||
{
|
||||
mc = Regex.Matches(uplayEntryLines[i], @"relative: (.*)");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
// Lookup the GameId within the registry key
|
||||
mc = Regex.Matches(uplayEntryLines[i], @"Installs\\(\d+)\\InstallDir");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
gameId = mc[0].Groups[1].ToString();
|
||||
gotGameId = true;
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: Found gameId = {gameId}");
|
||||
}
|
||||
mc = Regex.Matches(uplayEntryLines[i], @"HKEY_LOCAL_MACHINE\\(.*?)\\InstallDir");
|
||||
if (mc.Count > 0)
|
||||
{
|
||||
gameRegistryKey = mc[0].Groups[1].ToString();
|
||||
gameRegistryKey = gameRegistryKey.Replace(@"Ubisoft", @"WOW6432Node\Ubisoft");
|
||||
gotGameRegistryKey = true;
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: Found gameId = {gameId} and gameRegistryKey = {gameRegistryKey}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: Found gameRegistryKey = {gameRegistryKey}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,8 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
[assembly: AssemblyVersion("1.0.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.6.0")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
@ -150,7 +150,7 @@ namespace DisplayMagician
|
||||
AutoSuggestShortcutName();
|
||||
}
|
||||
|
||||
RefreshValidity();
|
||||
//RefreshValidity();
|
||||
|
||||
}
|
||||
|
||||
@ -2077,66 +2077,55 @@ namespace DisplayMagician
|
||||
}
|
||||
else if (Category.Equals(ShortcutCategory.Game))
|
||||
{
|
||||
GameLibrary gameLibraryToUse = null;
|
||||
|
||||
// If the game is a Steam Game we check for that
|
||||
if (GameLibrary.Equals(SupportedGameLibraryType.Steam))
|
||||
{
|
||||
// We now need to get the SteamGame info
|
||||
gameLibraryToUse = SteamLibrary.GetLibrary();
|
||||
}
|
||||
// If the game is a Uplay Uplay Game we check for that
|
||||
else if (GameLibrary.Equals(SupportedGameLibraryType.Uplay))
|
||||
{
|
||||
// We now need to get the Uplay Game info
|
||||
gameLibraryToUse = UplayLibrary.GetLibrary();
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
else if (GameLibrary.Equals(SupportedGameLibraryType.Origin))
|
||||
{
|
||||
// We now need to get the Uplay Game info
|
||||
gameLibraryToUse = OriginLibrary.GetLibrary();
|
||||
}
|
||||
|
||||
// If the game is a Steam Game we check for that
|
||||
|
||||
SteamLibrary steamLibrary = SteamLibrary.GetLibrary();
|
||||
// First check if Steam is installed
|
||||
// Check if Steam is installed and error if it isn't
|
||||
if (!steamLibrary.IsGameLibraryInstalled)
|
||||
if (!gameLibraryToUse.IsGameLibraryInstalled)
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "SteamNotInstalled";
|
||||
error.Name = $"{gameLibraryToUse.GameLibraryName}NotInstalled";
|
||||
error.Validity = ShortcutValidity.Error;
|
||||
error.Message = $"Steam is not installed on this computer.";
|
||||
error.Message = $"{gameLibraryToUse.GameLibraryName} is not installed on this computer.";
|
||||
_shortcutErrors.Add(error);
|
||||
if (worstError != ShortcutValidity.Error)
|
||||
worstError = ShortcutValidity.Error;
|
||||
}
|
||||
|
||||
// We need to look up details about the game
|
||||
if (!steamLibrary.ContainsGameById(GameAppId))
|
||||
if (!gameLibraryToUse.ContainsGameById(GameAppId))
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "SteamGameNotInstalled";
|
||||
error.Name = "{gameLibraryToUse.GameLibraryName}GameNotInstalled";
|
||||
error.Validity = ShortcutValidity.Error;
|
||||
error.Message = $"The Steam Game with AppID '{GameAppId}' is not installed on this computer.";
|
||||
error.Message = $"The {gameLibraryToUse.GameLibraryName} Game with AppID '{GameAppId}' is not installed on this computer.";
|
||||
_shortcutErrors.Add(error);
|
||||
if (worstError != ShortcutValidity.Error)
|
||||
worstError = ShortcutValidity.Error;
|
||||
}
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
else if (GameLibrary.Equals(SupportedGameLibraryType.Uplay))
|
||||
{
|
||||
UplayLibrary uplayLibrary = UplayLibrary.GetLibrary();
|
||||
// First check if Uplay is installed
|
||||
// Check if Uplay is installed and error if it isn't
|
||||
if (!uplayLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "UplayNotInstalled";
|
||||
error.Validity = ShortcutValidity.Error;
|
||||
error.Message = $"Uplay is not installed on this computer.";
|
||||
_shortcutErrors.Add(error);
|
||||
if (worstError != ShortcutValidity.Error)
|
||||
worstError = ShortcutValidity.Error;
|
||||
}
|
||||
|
||||
// We need to look up details about the game
|
||||
if (!uplayLibrary.ContainsGame(GameAppId))
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "UplayGameNotInstalled";
|
||||
error.Validity = ShortcutValidity.Error;
|
||||
error.Message = $"The Uplay Game with AppID '{GameAppId}' is not installed on this computer.";
|
||||
_shortcutErrors.Add(error);
|
||||
if (worstError != ShortcutValidity.Error)
|
||||
worstError = ShortcutValidity.Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the Audio Device is still valid (if one is specified)
|
||||
CoreAudioController audioController = ShortcutRepository.AudioController;
|
||||
if (ChangeAudioDevice)
|
||||
|
@ -1023,8 +1023,7 @@ namespace DisplayMagician
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Executable {processNameToLookFor} has exited.");
|
||||
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Executable {processNameToLookFor} has exited.");
|
||||
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the executable {shortcutToUse.ExecutableNameAndPath} has closed.");
|
||||
// Tell the user that the application has closed
|
||||
@ -1063,11 +1062,11 @@ namespace DisplayMagician
|
||||
// We now need to get the Uplay Game info
|
||||
gameLibraryToUse = UplayLibrary.GetLibrary();
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
// If the game is an Origin Game we check for that
|
||||
else if (shortcutToUse.GameLibrary.Equals(SupportedGameLibraryType.Origin))
|
||||
{
|
||||
// We now need to get the Uplay Game info
|
||||
gameLibraryToUse = UplayLibrary.GetLibrary();
|
||||
// We now need to get the Origin Game info
|
||||
gameLibraryToUse = OriginLibrary.GetLibrary();
|
||||
}
|
||||
|
||||
gameToRun = gameLibraryToUse.GetGameById(shortcutToUse.GameAppId);
|
||||
@ -1119,7 +1118,7 @@ namespace DisplayMagician
|
||||
Thread.Sleep(500);
|
||||
|
||||
// Wait for GameLibrary to start
|
||||
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
{
|
||||
|
||||
// If we have found one or more processes then we should be good to go
|
||||
@ -1136,14 +1135,96 @@ namespace DisplayMagician
|
||||
|
||||
}
|
||||
|
||||
// Check whether GameLibrary is updating (if it supports finding that out!)
|
||||
// Note - this is the scaffolding in place for the future. It will allow future ability to
|
||||
// detect game library updates if I can find a way of developing them per library in the future.
|
||||
if (gameLibraryToUse.IsUpdating)
|
||||
{
|
||||
logger.Info($"ShortcutRepository/RunShortcut: GameLibrary {gameLibraryToUse.GameLibraryName} has started updating itself.");
|
||||
|
||||
// Now we want to tell the user we're updating the game library
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=updating{gameLibraryToUse.GameLibraryName}", ToastActivationType.Foreground)
|
||||
.AddText($"Updating {gameLibraryToUse.GameLibraryName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for {gameLibraryToUse.GameLibraryName} Game Library to update itself...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Wait for up to 5 minutes for GameLibrary to update
|
||||
for (int secs = 0; secs <= 5000; secs += 500)
|
||||
{
|
||||
|
||||
// If the game library has finished updating then let's break, and get to the next step....
|
||||
if (!gameLibraryToUse.IsUpdating)
|
||||
{
|
||||
logger.Info($"ShortcutRepository/RunShortcut: GameLibrary {gameLibraryToUse.GameLibraryName} has finished updating.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's wait a little while while the GameLibrary is updating
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Delay 5secs
|
||||
Thread.Sleep(5000);
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Pausing to let the game library start the game.");
|
||||
Thread.Sleep(5000);
|
||||
|
||||
// Store the Process ID for later
|
||||
//IPCService.GetInstance().HoldProcessId = gameLibraryProcesses.FirstOrDefault()?.Id ?? 0;
|
||||
//IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Check whether Game itself is updating (if it supports finding that out!)
|
||||
// Note - this is the scaffolding in place for the future. It will allow future ability to
|
||||
// detect game library updates if I can find a way of developing them per library in the future.
|
||||
if (gameToRun.IsUpdating)
|
||||
{
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Game {gameToRun.Name} is being updated so we'll wait up to 15 mins until it's finished.");
|
||||
// Now we want to tell the user we're updating the game
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=updating{gameToRun.Name}", ToastActivationType.Foreground)
|
||||
.AddText($"Updating {gameToRun.Name}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for {gameToRun.Name} Game to update...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
// Wait for up to 15 minutes for the Game to update
|
||||
for (int secs = 0; secs <= 15000; secs += 500)
|
||||
{
|
||||
|
||||
// If the game library has finished updating then let's break, and get to the next step....
|
||||
if (!gameToRun.IsUpdating)
|
||||
{
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Game {gameToRun.Name} has finished updating.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's wait a little while while the GameLibrary is updating
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// At this point, if the user wants to actually monitor a different process,
|
||||
// then we actually need to monitor that instead
|
||||
if (shortcutToUse.MonitorDifferentGameExe)
|
||||
@ -1158,24 +1239,6 @@ namespace DisplayMagician
|
||||
notifyIcon.Text = $"DisplayMagician: Running {gameToRun.Name.Substring(0, 41)}...";
|
||||
Application.DoEvents();
|
||||
|
||||
// Now we want to tell the user we're running a game!
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the {altGameProcessToMonitor} alternative game process to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Now look for the thing we're supposed to monitor
|
||||
// and wait until it starts up
|
||||
List<Process> processesToMonitor = new List<Process>();
|
||||
@ -1196,17 +1259,137 @@ namespace DisplayMagician
|
||||
// any processes yet
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
// make sure we have things to monitor and alert if not
|
||||
// make sure we have an alternative game executable to monitor
|
||||
if (processesToMonitor.Count == 0)
|
||||
{
|
||||
logger.Error($"ShortcutRepository/RunShortcut: No Alternative Game Executable '{altGameProcessToMonitor}' processes found before waiting timeout. DisplayMagician was unable to find any processes before the {shortcutToUse.StartTimeout} second timeout");
|
||||
// if we didn't find an alternative game exectuable to monitor, then we need to go for the game executable itself as a fall back
|
||||
logger.Error($"ShortcutRepository/RunShortcut: No Alternative Game Executable '{altGameProcessToMonitor}' processes found before waiting timeout. DisplayMagician was unable to find any alternative processes before the {shortcutToUse.StartTimeout} second timeout");
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Ignoring monitoring Alternative Game Executable '{altGameProcessToMonitor}' processes. Reverting back to monitoring Game executables '{gameToRun.ProcessName}' instead.");
|
||||
|
||||
// we wait until the game has started running (*allows for updates to occur)
|
||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
{
|
||||
|
||||
if (gameToRun.IsRunning)
|
||||
{
|
||||
// The game is running! So now we continue processing
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{gameToRun.Name}' process has started");
|
||||
break;
|
||||
}
|
||||
|
||||
// if we have things to monitor, then we should start to wait for them
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Waiting for alternative game proocess {altGameProcessToMonitor} to exit.");
|
||||
if (processesToMonitor.Count > 0)
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
|
||||
}
|
||||
|
||||
// If the game still isn't running then there is an issue so tell the user and revert things back
|
||||
if (!gameToRun.IsRunning)
|
||||
{
|
||||
logger.Error($"ShortcutRepository/RunShortcut: The Game {gameToRun.Name} didn't start for some reason (or the game uses a starter exe that launches the game itself)! so reverting changes back if needed...");
|
||||
logger.Warn($"ShortcutRepository/RunShortcut: We were monitoring {gameToRun.ExePath}. You may need to manually add an alternative game executable to monitor - please run the game manually and check if another executable in {Path.GetDirectoryName(gameToRun.ExePath)} is run, and then monitor that instead.");
|
||||
// Now we want to tell the user we couldn't start the game!
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=errorRunning{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Could not detect {shortcutToUse.GameName} starting", hintMaxLines: 1)
|
||||
.AddText($"Could not detect {shortcutToUse.GameName} Game starting, so reverting changes back if needed. You may need to monitor a different game executable.");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// The game has started correctly so we continue to monitor it!
|
||||
|
||||
// Tell the user
|
||||
// Now we want to tell the user we're running a game!
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the {gameToRun.ProcessName} game process to exit as {altGameProcessToMonitor} alternative game executable wasn't found...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// This is the main waiting thread!
|
||||
// Wait for the game to exit
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: waiting for {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit.");
|
||||
while (true)
|
||||
{
|
||||
if (!gameToRun.IsRunning)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} is no longer running (IsRunning is false).");
|
||||
break;
|
||||
}
|
||||
|
||||
// Send a message to windows so that it doesn't think
|
||||
// we're locked and try to kill us
|
||||
System.Threading.Thread.CurrentThread.Join(0);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
|
||||
|
||||
// Tell the user that the Game has closed
|
||||
// Construct the toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
|
||||
.AddText($"{shortcutToUse.GameName} was closed", hintMaxLines: 1)
|
||||
.AddText($"{shortcutToUse.GameName} game was exited.");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we found alternative game executable processes, so we'll just monitor them
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Waiting for alternative game proocess {altGameProcessToMonitor} to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {processesToMonitor.Count} Alternative Game Executable '{altGameProcessToMonitor}' processes are still running");
|
||||
|
||||
// Now we want to tell the user we're monitoring the alternative executables!
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the {altGameProcessToMonitor} alternative game process to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
while (true)
|
||||
{
|
||||
processesToMonitor = Process.GetProcessesByName(altGameProcessToMonitor).ToList();
|
||||
@ -1223,9 +1406,7 @@ namespace DisplayMagician
|
||||
System.Threading.Thread.CurrentThread.Join(0);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Alternative Game Executable {altGameProcessToMonitor} has exited.");
|
||||
|
||||
// Tell the user that the Alt Game Executable has closed
|
||||
// Construct the toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
@ -1242,7 +1423,7 @@ namespace DisplayMagician
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1276,7 +1457,7 @@ namespace DisplayMagician
|
||||
|
||||
// Now we know the game library app is running then
|
||||
// we wait until the game has started running (*allows for updates to occur)
|
||||
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
{
|
||||
|
||||
if (gameToRun.IsRunning)
|
||||
@ -1291,9 +1472,32 @@ namespace DisplayMagician
|
||||
|
||||
}
|
||||
|
||||
// Wait 5 more seconds for the game process to spawn
|
||||
// Thread.Sleep(5000);
|
||||
// If the game still isn't running then there is an issue so tell the user and revert things back
|
||||
if (!gameToRun.IsRunning)
|
||||
{
|
||||
logger.Error($"ShortcutRepository/RunShortcut: The Game {gameToRun.Name} didn't start for some reason (or the game uses a starter exe that launches the game itself)! so reverting changes back if needed...");
|
||||
logger.Warn($"ShortcutRepository/RunShortcut: We were monitoring {gameToRun.ExePath}. You may need to manually add an alternative game executable to monitor - please run the game manually and check if another executable in {Path.GetDirectoryName(gameToRun.ExePath)} is run, and then monitor that instead.");
|
||||
// Now we want to tell the user we couldn't start the game!
|
||||
// Construct the Windows toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=errorRunning{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Could not detect {shortcutToUse.GameName} starting", hintMaxLines: 1)
|
||||
.AddText($"Could not detect {shortcutToUse.GameName} Game starting, so reverting changes back if needed. You may need to monitor a different game executable.");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the main waiting thread!
|
||||
// Wait for the game to exit
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: waiting for {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit.");
|
||||
@ -1310,7 +1514,6 @@ namespace DisplayMagician
|
||||
System.Threading.Thread.CurrentThread.Join(0);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
Console.WriteLine($"{gameToRun.Name} has exited.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
|
||||
|
||||
// Tell the user that the Game has closed
|
||||
@ -1329,15 +1532,14 @@ namespace DisplayMagician
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"ShortcutRepository/RunShortcut: Error starting the {gameToRun.Name} {gameToRun.GameLibrary} Game as the game wasn't found.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,12 +87,12 @@
|
||||
<Version>4.0.0-alpha5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Costura.Fody">
|
||||
<Version>5.0.2</Version>
|
||||
<Version>5.3.0</Version>
|
||||
<IncludeAssets>compile; runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fody">
|
||||
<Version>6.4.0</Version>
|
||||
<Version>6.5.1</Version>
|
||||
<!-- <IncludeAssets>compile; runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> -->
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
@ -19,12 +19,12 @@
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of (.NET Core) runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of (.NET Core) runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||
@ -55,7 +55,12 @@
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if (.NET Core) runtime assemblies are also embedded.</xs:documentation>
|
||||
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||
@ -90,12 +95,12 @@
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of (.NET Core) runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of (.NET Core) runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||
|
@ -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.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
[assembly: AssemblyVersion("1.0.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.6.0")]
|
@ -31,6 +31,7 @@
|
||||
<Pedantic>True</Pedantic>
|
||||
<WixVariables>
|
||||
</WixVariables>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
@ -38,6 +39,7 @@
|
||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||
<Pedantic>True</Pedantic>
|
||||
<DefineConstants>DisplayMagicianFilesDir=H:\vscode-projects\DisplayMagician\DisplayMagician\bin\Debug</DefineConstants>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CustomDialogs\LicenseAgreementDialogOverwritten.wxs" />
|
||||
|
@ -6,10 +6,10 @@
|
||||
-->
|
||||
<?define MajorVersion="1" ?>
|
||||
<?define MinorVersion="0" ?>
|
||||
<?define BuildVersion="5" ?>
|
||||
<?define PatchVersion="6" ?>
|
||||
<!-- Revision is NOT used by WiX in the upgrade procedure -->
|
||||
<!-- Full version number to display -->
|
||||
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>
|
||||
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.PatchVersion)" ?>
|
||||
|
||||
<!--
|
||||
Upgrade code HAS to be the same for all updates.
|
||||
|
@ -116,7 +116,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>12.0.3</Version>
|
||||
<Version>13.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NHotkey">
|
||||
<Version>2.1.0</Version>
|
||||
@ -125,7 +125,7 @@
|
||||
<Version>2.1.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NLog">
|
||||
<Version>4.7.8</Version>
|
||||
<Version>4.7.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NvAPIWrapper.Net">
|
||||
<Version>0.8.1.101</Version>
|
||||
|
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
[assembly: AssemblyVersion("1.0.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.6.0")]
|
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
[assembly: AssemblyVersion("1.0.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.6.0")]
|
@ -13,10 +13,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="nunit" Version="3.13.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="nunit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "1.0.5.0",
|
||||
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.5/DisplayMagicianSetup-v1.0.5.msi",
|
||||
"version": "1.0.6.0",
|
||||
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.6/DisplayMagicianSetup-v1.0.6.msi",
|
||||
"changelog": "https://github.com/terrymacdonald/DisplayMagician/releases",
|
||||
"mandatory": {
|
||||
"value": false,
|
||||
@ -8,7 +8,7 @@
|
||||
"mode": 0
|
||||
},
|
||||
"checksum": {
|
||||
"value": "36273CAEB4E7FE006ED48400CC243B0D01CE4AEFCF8F399A9641B7C124245F79",
|
||||
"value": "078DAE73B1648410F7AB9E21392B7C55A9EA8C1980AC468B2AC2951F3E49853E",
|
||||
"hashingAlgorithm": "SHA256"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user