mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Merge branch 'release/1.0.5' into main
This commit is contained in:
commit
001853b2c5
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1,4 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [terrymacdonald]
|
||||
custom: ["https://www.buymeacoffee.com/displaymagician", Buy Me a Coffee]
|
||||
custom: ["https://www.buymeacoffee.com/displaymagician"]
|
||||
|
@ -84,6 +84,7 @@
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.XML" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
@ -94,6 +95,7 @@
|
||||
<Compile Include="DesktopNotificationActivator.cs" />
|
||||
<Compile Include="DesktopNotificationManagerCompat.cs" />
|
||||
<Compile Include="GameLibraries\Game.cs" />
|
||||
<Compile Include="GameLibraries\GameLibrary.cs" />
|
||||
<Compile Include="GameLibraries\GameUtils.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\AppInfo.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\EUniverse.cs" />
|
||||
@ -101,13 +103,14 @@
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\PackageInfo.cs" />
|
||||
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
|
||||
<Compile Include="GameLibraries\UplayConfigurationParser\UplayConfigurationParser.cs" />
|
||||
<Compile Include="GameLibraries\OriginGame.cs" />
|
||||
<Compile Include="GameLibraries\OriginLibrary.cs" />
|
||||
<Compile Include="GameLibraries\UplayLibrary.cs" />
|
||||
<Compile Include="GameLibraries\SteamLibrary.cs" />
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<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>
|
||||
|
@ -3,10 +3,17 @@
|
||||
public class Game
|
||||
{
|
||||
|
||||
#region Properties
|
||||
public virtual int Id { get; set; }
|
||||
public enum GameStartMode
|
||||
{
|
||||
URI
|
||||
}
|
||||
|
||||
public virtual SupportedGameLibrary GameLibrary { get; }
|
||||
|
||||
|
||||
#region Properties
|
||||
public virtual string Id { get; set; }
|
||||
|
||||
public virtual SupportedGameLibraryType GameLibrary { get; }
|
||||
|
||||
public virtual bool IsRunning { get; set; }
|
||||
|
||||
@ -24,11 +31,18 @@
|
||||
|
||||
public virtual string ProcessName { get; set; }
|
||||
|
||||
public virtual GameStartMode StartMode { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public virtual bool CopyTo(SteamGame steamGame)
|
||||
public virtual string GetStartURI(string gameArguments = "")
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public virtual bool CopyTo(Game steamGame)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
113
DisplayMagician/GameLibraries/GameLibrary.cs
Normal file
113
DisplayMagician/GameLibraries/GameLibrary.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public enum SupportedGameLibraryType
|
||||
{
|
||||
Unknown,
|
||||
Steam,
|
||||
Uplay,
|
||||
Origin
|
||||
}
|
||||
|
||||
public class GameLibrary
|
||||
{
|
||||
|
||||
public struct GameAppInfo
|
||||
{
|
||||
public string GameID;
|
||||
public string GameName;
|
||||
public string GameExePath;
|
||||
public string GameInstallDir;
|
||||
public string GameIconPath;
|
||||
}
|
||||
|
||||
#region Class Properties
|
||||
public virtual List<Game> AllInstalledGames { get; set; }
|
||||
|
||||
public virtual int InstalledGameCount { get; set; }
|
||||
|
||||
public virtual string GameLibraryName { get; set; }
|
||||
|
||||
public virtual SupportedGameLibraryType GameLibraryType { get; set; }
|
||||
|
||||
public virtual string GameLibraryExe { get; set; }
|
||||
|
||||
public virtual string GameLibraryPath { get; set; }
|
||||
|
||||
public virtual bool IsGameLibraryInstalled { get; set; }
|
||||
|
||||
public virtual bool IsRunning { get; set; }
|
||||
|
||||
public virtual List<string> GameLibraryProcesses { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
public virtual bool AddGame(Game game)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool RemoveGame(Game game)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool RemoveGameById(string gameId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool RemoveGame(string gameNameOrId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool ContainsGame(Game game)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool ContainsGameById(string gameId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool ContainsGame(string gameNameOrId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public virtual Game GetGame(string gameNameOrId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual Game GetGameById(string gameId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool LoadInstalledGames()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
public class GameLibraryException : Exception
|
||||
{
|
||||
public GameLibraryException() { }
|
||||
public GameLibraryException(string message) : base(message) { }
|
||||
public GameLibraryException(string message, Exception inner) : base(message, inner) { }
|
||||
protected GameLibraryException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
|
||||
}
|
210
DisplayMagician/GameLibraries/OriginGame.cs
Normal file
210
DisplayMagician/GameLibraries/OriginGame.cs
Normal file
@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using DisplayMagician.Resources;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public class OriginGame : Game
|
||||
{
|
||||
private string _originGameId;
|
||||
private string _originGameName;
|
||||
private string _originGameExePath;
|
||||
private string _originGameDir;
|
||||
private string _originGameExe;
|
||||
private string _originGameProcessName;
|
||||
private string _originGameIconPath;
|
||||
//private string _originURI;
|
||||
private static readonly OriginLibrary _originGameLibrary = OriginLibrary.GetLibrary();
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
static OriginGame()
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback +=
|
||||
(send, certificate, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
|
||||
|
||||
public OriginGame(string originGameId, string originGameName, string originGameExePath, string originGameIconPath)
|
||||
{
|
||||
|
||||
//_gameRegistryKey = $@"{OriginLibrary.registryOriginInstallsKey}\\{OriginGameId}";
|
||||
_originGameId = originGameId;
|
||||
_originGameName = originGameName;
|
||||
_originGameExePath = originGameExePath;
|
||||
_originGameDir = Path.GetDirectoryName(originGameExePath);
|
||||
_originGameExe = Path.GetFileName(_originGameExePath);
|
||||
_originGameProcessName = Path.GetFileNameWithoutExtension(_originGameExePath);
|
||||
_originGameIconPath = originGameIconPath;
|
||||
|
||||
}
|
||||
|
||||
public override string Id
|
||||
{
|
||||
get => _originGameId;
|
||||
set => _originGameId = value;
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get => _originGameName;
|
||||
set => _originGameName = value;
|
||||
}
|
||||
|
||||
public override SupportedGameLibraryType GameLibrary
|
||||
{
|
||||
get => SupportedGameLibraryType.Origin;
|
||||
}
|
||||
|
||||
public override string IconPath
|
||||
{
|
||||
get => _originGameIconPath;
|
||||
set => _originGameIconPath = value;
|
||||
}
|
||||
|
||||
public override string ExePath
|
||||
{
|
||||
get => _originGameExePath;
|
||||
set => _originGameExePath = value;
|
||||
}
|
||||
|
||||
public override string Directory
|
||||
{
|
||||
get => _originGameDir;
|
||||
set => _originGameDir = value;
|
||||
}
|
||||
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
int numGameProcesses = 0;
|
||||
List<Process> gameProcesses = Process.GetProcessesByName(_originGameProcessName).ToList();
|
||||
foreach (Process gameProcess in gameProcesses)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (gameProcess.ProcessName.Equals(_originGameProcessName))
|
||||
numGameProcesses++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Debug(ex, $"OriginGame/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 assume that the process is a game process
|
||||
// as it matched the original process search
|
||||
numGameProcesses++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filePath.StartsWith(_originGameExePath))
|
||||
numGameProcesses++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (numGameProcesses > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Have to do much more research to figure out how to detect when Origin is updating a game
|
||||
/*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
|
||||
{
|
||||
get => GameStartMode.URI;
|
||||
}
|
||||
|
||||
public override string GetStartURI(string gameArguments = "")
|
||||
{
|
||||
string address = $"origin2://game/launch?offerIds={_originGameId}";
|
||||
if (String.IsNullOrWhiteSpace(gameArguments))
|
||||
{
|
||||
address += "/" + gameArguments;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public bool CopyTo(OriginGame OriginGame)
|
||||
{
|
||||
if (!(OriginGame is OriginGame))
|
||||
return false;
|
||||
|
||||
// Copy all the game data over to the other game
|
||||
OriginGame.IconPath = IconPath;
|
||||
OriginGame.Id = Id;
|
||||
OriginGame.Name = Name;
|
||||
OriginGame.ExePath = ExePath;
|
||||
OriginGame.Directory = Directory;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var name = _originGameName;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
name = Language.Unknown;
|
||||
}
|
||||
|
||||
if (IsRunning)
|
||||
{
|
||||
return name + " " + Language.Running;
|
||||
}
|
||||
|
||||
/*if (IsUpdating)
|
||||
{
|
||||
return name + " " + Language.Updating;
|
||||
}*/
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
728
DisplayMagician/GameLibraries/OriginLibrary.cs
Normal file
728
DisplayMagician/GameLibraries/OriginLibrary.cs
Normal file
@ -0,0 +1,728 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using System.Web;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public sealed class OriginLibrary : GameLibrary
|
||||
{
|
||||
#region Class Variables
|
||||
// Static members are 'eagerly initialized', that is,
|
||||
// immediately when class is loaded for the first time.
|
||||
// .NET guarantees thread safety for static initialization
|
||||
private static readonly OriginLibrary _instance = new OriginLibrary();
|
||||
|
||||
|
||||
// Common items to the class
|
||||
private List<Game> _allOriginGames = new List<Game>();
|
||||
private string OriginAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private string _originExe;
|
||||
private string _originPath;
|
||||
private string _originLocalContent = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Origin");
|
||||
private bool _isOriginInstalled = false;
|
||||
private List<string> _originProcessList = new List<string>(){ "origin" };
|
||||
|
||||
//private string _originConfigVdfFile;
|
||||
internal string registryOriginLauncherKey = @"SOFTWARE\WOW6432Node\Origin";
|
||||
//internal string registryOriginInstallsKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs";
|
||||
//internal string registryOriginOpenCmdKey = @"SOFTWARE\Classes\Origin\Shell\Open\Command";
|
||||
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
// Other constants that are useful
|
||||
#endregion
|
||||
|
||||
#region Class Constructors
|
||||
static OriginLibrary() { }
|
||||
|
||||
private OriginLibrary()
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.Trace($"OriginLibrary/OriginLibrary: Origin launcher registry key = HKLM\\{registryOriginLauncherKey}");
|
||||
// Find the OriginExe location, and the OriginPath for later
|
||||
RegistryKey OriginInstallKey = Registry.LocalMachine.OpenSubKey(registryOriginLauncherKey, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
if (OriginInstallKey == null)
|
||||
return;
|
||||
_originExe = OriginInstallKey.GetValue("ClientPath", @"C:\Program Files (x86)\Origin\Origin.exe").ToString();
|
||||
_originPath = _originExe;
|
||||
_originPath = _originPath.Replace(@"\Origin.exe", "");
|
||||
if (File.Exists(_originExe))
|
||||
{
|
||||
logger.Info($"OriginLibrary/OriginLibrary: Origin library is installed in {_originPath}. Found {_originExe}");
|
||||
_isOriginInstalled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"OriginLibrary/OriginLibrary: Origin library is not installed!");
|
||||
}
|
||||
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/OriginLibrary: The user does not have the permissions required to read the Origin ClientPath registry key.");
|
||||
}
|
||||
catch(ObjectDisposedException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/OriginLibrary: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin ClientPath registry key (closed keys cannot be accessed).");
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/OriginLibrary: The Origin ClientPath registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/OriginLibrary: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Class Properties
|
||||
public override List<Game> AllInstalledGames
|
||||
{
|
||||
get
|
||||
{
|
||||
// Load the Origin Games from Origin Client if needed
|
||||
if (_allOriginGames.Count == 0)
|
||||
LoadInstalledGames();
|
||||
return _allOriginGames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override int InstalledGameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _allOriginGames.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GameLibraryName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Origin";
|
||||
}
|
||||
}
|
||||
|
||||
public override SupportedGameLibraryType GameLibraryType
|
||||
{
|
||||
get
|
||||
{
|
||||
return SupportedGameLibraryType.Origin;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GameLibraryExe
|
||||
{
|
||||
get
|
||||
{
|
||||
return _originExe;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GameLibraryPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _originPath;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsGameLibraryInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isOriginInstalled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Process> originLibraryProcesses = new List<Process>();
|
||||
|
||||
foreach (string originLibraryProcessName in _originProcessList)
|
||||
{
|
||||
// Look for the processes with the ProcessName we sorted out earlier
|
||||
originLibraryProcesses.AddRange(Process.GetProcessesByName(originLibraryProcessName));
|
||||
}
|
||||
|
||||
// If we have found one or more processes then we should be good to go
|
||||
// so let's break, and get to the next step....
|
||||
if (originLibraryProcesses.Count > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
{
|
||||
return _originProcessList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
public static OriginLibrary GetLibrary()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
public override bool AddGame(Game originGame)
|
||||
{
|
||||
if (!(originGame is OriginGame))
|
||||
return false;
|
||||
|
||||
// Doublecheck if it already exists
|
||||
// Because then we just update the one that already exists
|
||||
if (ContainsGame(originGame))
|
||||
{
|
||||
logger.Debug($"OriginLibrary/AddOriginGame: Updating Origin game {originGame.Name} in our Origin library");
|
||||
// We update the existing Shortcut with the data over
|
||||
OriginGame originGameToUpdate = (OriginGame)GetGame(originGame.Id.ToString());
|
||||
originGame.CopyTo(originGameToUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Debug($"OriginLibrary/AddOriginGame: Adding Origin game {originGame.Name} to our Origin library");
|
||||
// Add the OriginGame to the list of OriginGames
|
||||
_allOriginGames.Add(originGame);
|
||||
}
|
||||
|
||||
//Doublecheck it's been added
|
||||
if (ContainsGame(originGame))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public override bool RemoveGame(Game originGame)
|
||||
{
|
||||
if (!(originGame is OriginGame))
|
||||
return false;
|
||||
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame: Removing Origin game {originGame.Name} from our Origin library");
|
||||
|
||||
// Remove the OriginGame from the list.
|
||||
int numRemoved = _allOriginGames.RemoveAll(item => item.Id.Equals(originGame.Id));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame: Removed Origin game with name {originGame.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame: Didn't remove Origin game with ID {originGame.Name} from the Origin Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new OriginLibraryException();
|
||||
}
|
||||
|
||||
public override bool RemoveGameById(string originGameId)
|
||||
{
|
||||
if (originGameId.Equals(0))
|
||||
return false;
|
||||
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame2: Removing Origin game with ID {originGameId} from the Origin library");
|
||||
|
||||
// Remove the OriginGame from the list.
|
||||
int numRemoved = _allOriginGames.RemoveAll(item => item.Id.Equals(originGameId));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame2: Removed Origin game with ID {originGameId}");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame2: Didn't remove Origin game with ID {originGameId} from the Origin Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new OriginLibraryException();
|
||||
}
|
||||
|
||||
public override bool RemoveGame(string originGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
||||
return false;
|
||||
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame3: Removing Origin game with Name or ID {originGameNameOrId} from the Origin library");
|
||||
|
||||
int numRemoved;
|
||||
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
numRemoved = _allOriginGames.RemoveAll(item => originGameNameOrId.Equals(item.Id));
|
||||
else
|
||||
numRemoved = _allOriginGames.RemoveAll(item => originGameNameOrId.Equals(item.Name));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame3: Removed Origin game with Name or UUID {originGameNameOrId} ");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"OriginLibrary/RemoveOriginGame3: Didn't remove Origin game with Name or UUID {originGameNameOrId} from the Origin Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new OriginLibraryException();
|
||||
|
||||
}
|
||||
|
||||
public override bool ContainsGame(Game originGame)
|
||||
{
|
||||
if (!(originGame is OriginGame))
|
||||
return false;
|
||||
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (testOriginGame.Id.Equals(originGame.Id))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool ContainsGameById(string originGameId)
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameId == testOriginGame.Id)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public override bool ContainsGame(string originGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
||||
return false;
|
||||
|
||||
|
||||
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameNameOrId.Equals(Convert.ToInt32(testOriginGame.Id)))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameNameOrId.Equals(testOriginGame.Name))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override Game GetGame(string originGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(originGameNameOrId))
|
||||
return null;
|
||||
|
||||
Match match = Regex.Match(originGameNameOrId, OriginAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameNameOrId.Equals(Convert.ToInt32(testOriginGame.Id)))
|
||||
return testOriginGame;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameNameOrId.Equals(testOriginGame.Name))
|
||||
return testOriginGame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public override Game GetGameById(string originGameId)
|
||||
{
|
||||
foreach (OriginGame testOriginGame in _allOriginGames)
|
||||
{
|
||||
if (originGameId == testOriginGame.Id)
|
||||
return testOriginGame;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private Dictionary<string, string> ParseOriginManifest(string path)
|
||||
{
|
||||
string encodedContents = File.ReadAllText(path);
|
||||
Dictionary<string, string> parameters = Regex.Matches(encodedContents, "([^?=&]+)(=([^&]*))?").Cast<Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
public override bool LoadInstalledGames()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (!_isOriginInstalled)
|
||||
{
|
||||
// Origin isn't installed, so we return an empty list.
|
||||
logger.Info($"OriginLibrary/LoadInstalledGames: Origin library is not installed");
|
||||
return false;
|
||||
}
|
||||
|
||||
var localContentPath = Path.Combine(_originLocalContent, "LocalContent");
|
||||
//var games = new Dictionary<string, GameInfo>();
|
||||
|
||||
if (Directory.Exists(localContentPath))
|
||||
{
|
||||
string[] packages = Directory.GetFiles(localContentPath, "*.mfst", SearchOption.AllDirectories);
|
||||
foreach (string package in packages)
|
||||
{
|
||||
try
|
||||
{
|
||||
GameAppInfo originGame = new GameAppInfo();
|
||||
originGame.GameID = Path.GetFileNameWithoutExtension(package);
|
||||
if (!originGame.GameID.StartsWith("Origin"))
|
||||
{
|
||||
// If the gameId doesn't start with origin, then we need to find it!
|
||||
// Get game id by fixing file via adding : before integer part of the name
|
||||
// for example OFB-EAST52017 converts to OFB-EAST:52017
|
||||
Match match = Regex.Match(originGame.GameID, @"^(.*?)(\d+)$");
|
||||
if (!match.Success)
|
||||
{
|
||||
logger.Warn("Failed to get game id from file " + package);
|
||||
continue;
|
||||
}
|
||||
|
||||
originGame.GameID = match.Groups[1].Value + ":" + match.Groups[2].Value;
|
||||
}
|
||||
|
||||
// Now we get the rest of the game information out of the manifest file
|
||||
Dictionary<string, string> manifestInfo = ParseOriginManifest(package);
|
||||
|
||||
if (manifestInfo.ContainsKey("ddinitialdownload") && manifestInfo["ddinitialdownload"] == "1")
|
||||
{
|
||||
// Origin is downloading and installing the game so we skip it
|
||||
continue;
|
||||
}
|
||||
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
|
||||
continue;
|
||||
}
|
||||
|
||||
originGame.GameInstallDir = null;
|
||||
if (manifestInfo.ContainsKey("dipinstallpath"))
|
||||
{
|
||||
// This is where Origin has installed this game
|
||||
originGame.GameInstallDir = HttpUtility.UrlDecode(manifestInfo["dipinstallpath"]);
|
||||
if (!Directory.Exists(originGame.GameInstallDir))
|
||||
{
|
||||
logger.Debug($"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
|
||||
|
||||
string gameInstallerData = Path.Combine(originGame.GameInstallDir, @"__Installer", @"installerdata.xml");
|
||||
|
||||
if (File.Exists(gameInstallerData))
|
||||
{
|
||||
// Now we parse the XML
|
||||
XDocument xdoc = XDocument.Load(gameInstallerData);
|
||||
originGame.GameName = xdoc.XPathSelectElement("/DiPManifest/gameTitles/gameTitle[@locale='en_US']").Value;
|
||||
string gameFilePath = xdoc.XPathSelectElement("/DiPManifest/runtime/launcher/filePath").Value;
|
||||
// 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"))
|
||||
{
|
||||
// The filePath contains a registry key lookup that we need to execute and replace
|
||||
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)
|
||||
{
|
||||
// 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}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
||||
string originGameInstallKeyName = mc[0].Groups[1].ToString();
|
||||
string originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
||||
|
||||
try
|
||||
{
|
||||
RegistryKey originGameInstallKey = Registry.LocalMachine.OpenSubKey(originGameInstallKeyName, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
if (originGameInstallKey == null)
|
||||
{
|
||||
// then we have a problem as we cannot find the game exe location!
|
||||
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);
|
||||
if (!File.Exists(originGameInstallLocation))
|
||||
{
|
||||
// then we have a problem as we cannot locate the game exe file to start!
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has gameexe we cannot find! originGameInstallLocation is {originGameInstallLocation}.");
|
||||
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 {}.");
|
||||
}
|
||||
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).");
|
||||
}
|
||||
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.");
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
}
|
||||
}
|
||||
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\\(.*)\](.*)");
|
||||
string originGameInstallKeyNameAndValue = mc[0].Groups[1].ToString();
|
||||
string originGameRestOfFile = mc[0].Groups[2].ToString();
|
||||
if (originGameInstallKeyNameAndValue == null)
|
||||
{
|
||||
// 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}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
mc = Regex.Matches(originGameInstallKeyNameAndValue, @"(.*)\\([^\\]*)");
|
||||
string originGameInstallKeyName = mc[0].Groups[1].ToString();
|
||||
string originGameInstallKeyValue = mc[0].Groups[2].ToString();
|
||||
|
||||
try
|
||||
{
|
||||
RegistryKey originGameInstallKey = Registry.LocalMachine.OpenSubKey(originGameInstallKeyName, RegistryKeyPermissionCheck.ReadSubTree);
|
||||
if (originGameInstallKey == null)
|
||||
{
|
||||
// then we have a problem as we cannot find the game exe location!
|
||||
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);
|
||||
if (!File.Exists(originGameInstallLocation))
|
||||
{
|
||||
// then we have a problem as we cannot locate the game exe file to start!
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} has gameexe we cannot find! originGameInstallLocation is {originGameInstallLocation}.");
|
||||
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 {}.");
|
||||
}
|
||||
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).");
|
||||
}
|
||||
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.");
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/LoadInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!File.Exists(originGame.GameExePath))
|
||||
{
|
||||
logger.Debug($"OriginLibrary/LoadInstalledGames: Origin game with ID {originGame.GameID} found but no game exe found at {originGame.GameExePath}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO check for icon! For now we will just use the exe one
|
||||
originGame.GameIconPath = originGame.GameExePath;
|
||||
|
||||
// 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
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, $"OriginLibrary/LoadInstalledGames: Failed to import installed Origin game {package}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"OriginLibrary/LoadInstalledGames: No Origin games installed in the Origin library");
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
catch (ArgumentNullException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: An argument supplied to the function is null.");
|
||||
}
|
||||
catch (NotSupportedException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/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, "OriginLibrary/GetAllInstalledGames: The path is longer than the maximum allowed by the operating system.");
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The user does not have the permissions required to read the Origin InstallDir registry key.");
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The Microsoft.Win32.RegistryKey is closed when trying to access the Origin InstallDir registry key (closed keys cannot be accessed).");
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The Origin InstallDir registry key has been marked for deletion so we cannot access the value dueing the OriginLibrary check.");
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
logger.Warn(ex, "OriginLibrary/GetAllInstalledGames: The user does not have the necessary registry rights to check whether Origin is installed.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
public class OriginLibraryException : GameLibraryException
|
||||
{
|
||||
public OriginLibraryException() { }
|
||||
public OriginLibraryException(string message) : base(message) { }
|
||||
public OriginLibraryException(string message, Exception inner) : base(message, inner) { }
|
||||
protected OriginLibraryException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
|
||||
}
|
@ -13,13 +13,14 @@ namespace DisplayMagician.GameLibraries
|
||||
public class SteamGame : Game
|
||||
{
|
||||
private string _gameRegistryKey;
|
||||
private int _steamGameId;
|
||||
private string _steamGameId;
|
||||
private string _steamGameName;
|
||||
private string _steamGameExePath;
|
||||
private string _steamGameDir;
|
||||
private string _steamGameExe;
|
||||
private string _steamGameProcessName;
|
||||
private string _steamGameIconPath;
|
||||
private static readonly SteamLibrary _steamGameLibrary = SteamLibrary.GetLibrary();
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
static SteamGame()
|
||||
@ -29,10 +30,10 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public SteamGame(int steamGameId, string steamGameName, string steamGameExePath, string steamGameIconPath)
|
||||
public SteamGame(string steamGameId, string steamGameName, string steamGameExePath, string steamGameIconPath)
|
||||
{
|
||||
|
||||
_gameRegistryKey = $@"{SteamLibrary.SteamAppsRegistryKey}\\{steamGameId}";
|
||||
_gameRegistryKey = $@"{_steamGameLibrary.SteamAppsRegistryKey}\\{steamGameId}";
|
||||
_steamGameId = steamGameId;
|
||||
_steamGameName = steamGameName;
|
||||
_steamGameExePath = steamGameExePath;
|
||||
@ -43,7 +44,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override int Id {
|
||||
public override string Id {
|
||||
get => _steamGameId;
|
||||
set => _steamGameId = value;
|
||||
}
|
||||
@ -54,8 +55,8 @@ namespace DisplayMagician.GameLibraries
|
||||
set => _steamGameName = value;
|
||||
}
|
||||
|
||||
public override SupportedGameLibrary GameLibrary {
|
||||
get => SupportedGameLibrary.Steam;
|
||||
public override SupportedGameLibraryType GameLibrary {
|
||||
get => SupportedGameLibraryType.Steam;
|
||||
}
|
||||
|
||||
public override string IconPath {
|
||||
@ -154,6 +155,21 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public override GameStartMode StartMode
|
||||
{
|
||||
get => GameStartMode.URI;
|
||||
}
|
||||
|
||||
public override string GetStartURI(string gameArguments = "")
|
||||
{
|
||||
string address = $"steam://rungameid/{Id}";
|
||||
if (String.IsNullOrWhiteSpace(gameArguments))
|
||||
{
|
||||
address += "/" + gameArguments;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public bool CopyInto(SteamGame steamGame)
|
||||
{
|
||||
if (!(steamGame is SteamGame))
|
||||
|
@ -11,33 +11,42 @@ using System.Diagnostics;
|
||||
|
||||
namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public static class SteamLibrary
|
||||
public sealed class SteamLibrary : GameLibrary
|
||||
{
|
||||
#region Class Variables
|
||||
// Common items to the class
|
||||
private static List<Game> _allSteamGames = new List<Game>();
|
||||
private static string steamAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private static string _steamExe;
|
||||
private static string _steamPath;
|
||||
private static string _steamConfigVdfFile;
|
||||
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
|
||||
#endregion
|
||||
|
||||
private struct SteamAppInfo
|
||||
{
|
||||
public int GameID;
|
||||
public string GameID;
|
||||
public string GameName;
|
||||
public List<string> GameExes;
|
||||
public string GameInstallDir;
|
||||
public string GameSteamIconPath;
|
||||
public string GameIconPath;
|
||||
}
|
||||
|
||||
#region Class Variables
|
||||
// Static members are 'eagerly initialized', that is,
|
||||
// immediately when class is loaded for the first time.
|
||||
// .NET guarantees thread safety for static initialization
|
||||
private static SteamLibrary _instance = new SteamLibrary();
|
||||
|
||||
// Common items to the class
|
||||
private List<Game> _allSteamGames = new List<Game>();
|
||||
private string steamAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private string _steamExe;
|
||||
private string _steamPath;
|
||||
private string _steamConfigVdfFile;
|
||||
private List<string> _steamProcessList = new List<string>() { "steam"};
|
||||
private string _registrySteamKey = @"SOFTWARE\WOW6432Node\Valve\Steam"; // under LocalMachine
|
||||
private string _registryAppsKey = $@"SOFTWARE\Valve\Steam\Apps"; // under CurrentUser
|
||||
private bool _isSteamInstalled = false;
|
||||
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
// Other constants that are useful
|
||||
#endregion
|
||||
|
||||
#region Class Constructors
|
||||
static SteamLibrary()
|
||||
static SteamLibrary() { }
|
||||
|
||||
private SteamLibrary()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -80,7 +89,7 @@ namespace DisplayMagician.GameLibraries
|
||||
#endregion
|
||||
|
||||
#region Class Properties
|
||||
public static List<Game> AllInstalledGames
|
||||
public override List<Game> AllInstalledGames
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -92,7 +101,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public static int InstalledSteamGameCount
|
||||
public override int InstalledGameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -100,7 +109,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static string SteamRegistryKey
|
||||
public string SteamRegistryKey
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -108,7 +117,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static string SteamAppsRegistryKey
|
||||
public string SteamAppsRegistryKey
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -116,7 +125,23 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static string SteamExe
|
||||
public override string GameLibraryName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Steam";
|
||||
}
|
||||
}
|
||||
|
||||
public override SupportedGameLibraryType GameLibraryType
|
||||
{
|
||||
get
|
||||
{
|
||||
return SupportedGameLibraryType.Steam;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GameLibraryExe
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -124,7 +149,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static string SteamPath
|
||||
public override string GameLibraryPath
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -132,7 +157,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsSteamInstalled
|
||||
public override bool IsGameLibraryInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -141,23 +166,58 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Process> steamLibraryProcesses = new List<Process>();
|
||||
|
||||
foreach (string steamLibraryProcessName in _steamProcessList)
|
||||
{
|
||||
// Look for the processes with the ProcessName we sorted out earlier
|
||||
steamLibraryProcesses.AddRange(Process.GetProcessesByName(steamLibraryProcessName));
|
||||
}
|
||||
|
||||
// If we have found one or more processes then we should be good to go
|
||||
// so let's break, and get to the next step....
|
||||
if (steamLibraryProcesses.Count > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
{
|
||||
return _steamProcessList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
public static bool AddSteamGame(SteamGame steamGame)
|
||||
public static SteamLibrary GetLibrary()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public override bool AddGame(Game steamGame)
|
||||
{
|
||||
if (!(steamGame is SteamGame))
|
||||
return false;
|
||||
|
||||
// Doublecheck if it already exists
|
||||
// Because then we just update the one that already exists
|
||||
if (ContainsSteamGame(steamGame))
|
||||
if (ContainsGame(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);
|
||||
SteamGame steamGameToUpdate = (SteamGame)GetGameById(steamGame.Id.ToString());
|
||||
steamGame.CopyTo(steamGameToUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -167,7 +227,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
//Doublecheck it's been added
|
||||
if (ContainsSteamGame(steamGame))
|
||||
if (ContainsGame(steamGame))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -176,7 +236,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool RemoveSteamGame(SteamGame steamGame)
|
||||
public override bool RemoveGame(Game steamGame)
|
||||
{
|
||||
if (!(steamGame is SteamGame))
|
||||
return false;
|
||||
@ -200,9 +260,9 @@ namespace DisplayMagician.GameLibraries
|
||||
throw new SteamLibraryException();
|
||||
}
|
||||
|
||||
public static bool RemoveSteamGame(int steamGameId)
|
||||
public override bool RemoveGameById(string steamGameId)
|
||||
{
|
||||
if (steamGameId<=0)
|
||||
if (steamGameId.Equals("0"))
|
||||
return false;
|
||||
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame2: Removing Steam game with ID {steamGameId} from the Steam library");
|
||||
@ -225,28 +285,28 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public static bool RemoveSteamGame(string steamGameNameOrUuid)
|
||||
public override bool RemoveGame(string steamGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(steamGameNameOrUuid))
|
||||
if (String.IsNullOrWhiteSpace(steamGameNameOrId))
|
||||
return false;
|
||||
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Removing Steam game with Name or UUID {steamGameNameOrUuid} from the Steam library");
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Removing Steam game with Name or UUID {steamGameNameOrId} from the Steam library");
|
||||
|
||||
int numRemoved;
|
||||
Match match = Regex.Match(steamGameNameOrUuid, steamAppIdRegex, RegexOptions.IgnoreCase);
|
||||
Match match = Regex.Match(steamGameNameOrId, steamAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrUuid.Equals(Convert.ToUInt32(item.Id)));
|
||||
numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrId.Equals(item.Id));
|
||||
else
|
||||
numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrUuid.Equals(item.Name));
|
||||
numRemoved = _allSteamGames.RemoveAll(item => steamGameNameOrId.Equals(item.Name));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Removed Steam game with Name or UUID {steamGameNameOrUuid} ");
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Removed Steam game with Name or UUID {steamGameNameOrId} ");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Didn't remove Steam game with Name or UUID {steamGameNameOrUuid} from the Steam Library");
|
||||
logger.Debug($"SteamLibrary/RemoveSteamGame3: Didn't remove Steam game with Name or UUID {steamGameNameOrId} from the Steam Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -254,7 +314,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool ContainsSteamGame(SteamGame steamGame)
|
||||
public override bool ContainsGame(Game steamGame)
|
||||
{
|
||||
if (!(steamGame is SteamGame))
|
||||
return false;
|
||||
@ -268,7 +328,7 @@ namespace DisplayMagician.GameLibraries
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ContainsSteamGame(string steamGameNameOrUuid)
|
||||
public override bool ContainsGame(string steamGameNameOrUuid)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(steamGameNameOrUuid))
|
||||
return false;
|
||||
@ -298,7 +358,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool ContainsSteamGame(int steamGameId)
|
||||
public override bool ContainsGameById(string steamGameId)
|
||||
{
|
||||
foreach (SteamGame testSteamGame in _allSteamGames)
|
||||
{
|
||||
@ -312,7 +372,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public static SteamGame GetSteamGame(string steamGameNameOrUuid)
|
||||
public override Game GetGame(string steamGameNameOrUuid)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(steamGameNameOrUuid))
|
||||
return null;
|
||||
@ -341,7 +401,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static SteamGame GetSteamGame(int steamGameId)
|
||||
public override Game GetGameById(string steamGameId)
|
||||
{
|
||||
foreach (SteamGame testSteamGame in _allSteamGames)
|
||||
{
|
||||
@ -353,7 +413,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool LoadInstalledGames()
|
||||
public override bool LoadInstalledGames()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -368,7 +428,7 @@ namespace DisplayMagician.GameLibraries
|
||||
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>();
|
||||
List<string> steamAppIdsInstalled = new List<string>();
|
||||
// Now look for what games app id's are actually installed on this computer
|
||||
using (RegistryKey steamAppsKey = Registry.CurrentUser.OpenSubKey(_registryAppsKey, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
@ -376,13 +436,13 @@ namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
//
|
||||
// Loop through the subKeys as they are the Steam Game IDs
|
||||
foreach (string steamGameKeyName in steamAppsKey.GetSubKeyNames())
|
||||
foreach (string steamAppId in steamAppsKey.GetSubKeyNames())
|
||||
{
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: Found SteamGameKeyName = {steamGameKeyName}");
|
||||
if (int.TryParse(steamGameKeyName, out int steamAppId))
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: Found SteamGameKeyName = {steamAppId}");
|
||||
if (!String.IsNullOrWhiteSpace(steamAppId))
|
||||
{
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: SteamGameKeyName is an int, so trying to see if it is an installed app");
|
||||
string steamGameKeyFullName = $"{_registryAppsKey}\\{steamGameKeyName}";
|
||||
string steamGameKeyFullName = $"{_registryAppsKey}\\{steamAppId}";
|
||||
using (RegistryKey steamGameKey = Registry.CurrentUser.OpenSubKey(steamGameKeyFullName, RegistryKeyPermissionCheck.ReadSubTree))
|
||||
{
|
||||
// If the Installed Value is set to 1, then the game is installed
|
||||
@ -398,7 +458,7 @@ namespace DisplayMagician.GameLibraries
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: {steamGameKeyFullName} does not contain an 'Installed' value so can't be a Steam App.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -424,7 +484,7 @@ namespace DisplayMagician.GameLibraries
|
||||
// - THe game installation dir
|
||||
// - Sometimes the game icon
|
||||
// - Sometimes the game executable name (from which we can get the icon)
|
||||
Dictionary<int, SteamAppInfo> steamAppInfo = new Dictionary<int, SteamAppInfo>();
|
||||
Dictionary<string, SteamAppInfo> steamAppInfo = new Dictionary<string, SteamAppInfo>();
|
||||
|
||||
string appInfoVdfFile = Path.Combine(_steamPath, "appcache", "appinfo.vdf");
|
||||
var newAppInfo = new AppInfo();
|
||||
@ -437,7 +497,7 @@ namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
// We only care about the appIDs we have listed as actual games
|
||||
// (The AppIds include all other DLC and Steam specific stuff too)
|
||||
int detectedAppID = Convert.ToInt32(app.AppID);
|
||||
string detectedAppID = app.AppID.ToString();
|
||||
if (steamAppIdsInstalled.Contains(detectedAppID))
|
||||
{
|
||||
|
||||
@ -468,7 +528,7 @@ namespace DisplayMagician.GameLibraries
|
||||
else if (common.Name == "clienticon")
|
||||
{
|
||||
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"));
|
||||
steamGameAppInfo.GameIconPath = Path.Combine(_steamPath, @"steam", @"games", String.Concat(common.Value, @".ico"));
|
||||
}
|
||||
else if (common.Name == "type")
|
||||
{
|
||||
@ -515,7 +575,7 @@ namespace DisplayMagician.GameLibraries
|
||||
if (steamAppType.Equals("Game",StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
steamAppInfo.Add(detectedAppID, steamGameAppInfo);
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: Adding Game with ID {detectedAppID} to the list of games");
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: Adding Game with ID {detectedAppID} '{steamGameAppInfo.GameName}' to the list of games");
|
||||
}
|
||||
|
||||
}
|
||||
@ -578,8 +638,9 @@ namespace DisplayMagician.GameLibraries
|
||||
Match appidMatches = appidRegex.Match(steamLibraryAppManifestText);
|
||||
if (appidMatches.Success)
|
||||
{
|
||||
if (int.TryParse(appidMatches.Groups[1].Value, out int steamGameId))
|
||||
if (!String.IsNullOrWhiteSpace(appidMatches.Groups[1].Value))
|
||||
{
|
||||
string steamGameId = appidMatches.Groups[1].Value;
|
||||
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))
|
||||
@ -593,32 +654,32 @@ 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 }");
|
||||
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)
|
||||
{
|
||||
foreach (string gameExe in steamAppInfo[steamGameId].GameExes)
|
||||
// And finally we try to populate the 'where', to see what gets run
|
||||
// And so we can extract the process name
|
||||
if (steamAppInfo[steamGameId].GameExes.Count > 0)
|
||||
{
|
||||
steamGameExe = Path.Combine(steamGameInstallDir, gameExe);
|
||||
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))
|
||||
foreach (string gameExe in steamAppInfo[steamGameId].GameExes)
|
||||
{
|
||||
logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Exe {steamGameExe} for Steam Game ID {steamGameId} at {steamGameInstallDir }");
|
||||
break;
|
||||
steamGameExe = Path.Combine(steamGameInstallDir, gameExe);
|
||||
logger.Trace($"SteamLibrary/LoadInstalledGames: Looking for Steam Game Exe {steamGameExe} for Steam Game ID {steamGameId} at {steamGameInstallDir }");
|
||||
// If the game executable exists, then we can proceed
|
||||
if (File.Exists(steamGameExe))
|
||||
{
|
||||
logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Exe {steamGameExe} for Steam Game ID {steamGameId} at {steamGameInstallDir }");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Next, we need to get the Icons we want to use, and make sure it's the latest one.
|
||||
string steamGameIconPath = "";
|
||||
// First of all, we attempt to use the Icon that Steam has cached, if it's available, as that will be updated to the latest
|
||||
if (File.Exists(steamAppInfo[steamGameId].GameSteamIconPath) && steamAppInfo[steamGameId].GameSteamIconPath.EndsWith(".ico"))
|
||||
if (File.Exists(steamAppInfo[steamGameId].GameIconPath) && steamAppInfo[steamGameId].GameIconPath.EndsWith(".ico"))
|
||||
{
|
||||
steamGameIconPath = steamAppInfo[steamGameId].GameSteamIconPath;
|
||||
steamGameIconPath = steamAppInfo[steamGameId].GameIconPath;
|
||||
logger.Debug($"SteamLibrary/LoadInstalledGames: Found Steam Game Icon Path {steamGameIconPath} for Steam Game ID {steamGameId} at {steamGameInstallDir }");
|
||||
|
||||
}
|
||||
@ -683,7 +744,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
public class SteamLibraryException : Exception
|
||||
public class SteamLibraryException : GameLibraryException
|
||||
{
|
||||
public SteamLibraryException() { }
|
||||
public SteamLibraryException(string message) : base(message) { }
|
||||
|
@ -10,14 +10,15 @@ namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public class UplayGame : Game
|
||||
{
|
||||
private string _gameRegistryKey;
|
||||
private int _uplayGameId;
|
||||
//private string _gameRegistryKey;
|
||||
private string _uplayGameId;
|
||||
private string _uplayGameName;
|
||||
private string _uplayGameExePath;
|
||||
private string _uplayGameDir;
|
||||
private string _uplayGameExe;
|
||||
private string _uplayGameProcessName;
|
||||
private string _uplayGameIconPath;
|
||||
private static readonly UplayLibrary _uplayGameLibrary = UplayLibrary.GetLibrary();
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
static UplayGame()
|
||||
@ -27,10 +28,10 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public UplayGame(int uplayGameId, string uplayGameName, string uplayGameExePath, string uplayGameIconPath)
|
||||
public UplayGame(string uplayGameId, string uplayGameName, string uplayGameExePath, string uplayGameIconPath)
|
||||
{
|
||||
|
||||
_gameRegistryKey = $@"{UplayLibrary.registryUplayInstallsKey}\\{uplayGameId}";
|
||||
//_gameRegistryKey = $@"{UplayLibrary.registryUplayInstallsKey}\\{uplayGameId}";
|
||||
_uplayGameId = uplayGameId;
|
||||
_uplayGameName = uplayGameName;
|
||||
_uplayGameExePath = uplayGameExePath;
|
||||
@ -41,7 +42,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override int Id
|
||||
public override string Id
|
||||
{
|
||||
get => _uplayGameId;
|
||||
set => _uplayGameId = value;
|
||||
@ -53,9 +54,9 @@ namespace DisplayMagician.GameLibraries
|
||||
set => _uplayGameName = value;
|
||||
}
|
||||
|
||||
public override SupportedGameLibrary GameLibrary
|
||||
public override SupportedGameLibraryType GameLibrary
|
||||
{
|
||||
get => SupportedGameLibrary.Uplay;
|
||||
get => SupportedGameLibraryType.Uplay;
|
||||
}
|
||||
|
||||
public override string IconPath
|
||||
@ -154,6 +155,25 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}*/
|
||||
|
||||
public override GameStartMode StartMode
|
||||
{
|
||||
get => GameStartMode.URI;
|
||||
}
|
||||
|
||||
public override string GetStartURI(string gameArguments = "")
|
||||
{
|
||||
string address = $"uplay://launch/{Id}";
|
||||
if (String.IsNullOrWhiteSpace(gameArguments))
|
||||
{
|
||||
address += "/" + gameArguments;
|
||||
}
|
||||
else
|
||||
{
|
||||
address += "/0";
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public bool CopyTo(UplayGame uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
|
@ -5,39 +5,42 @@ using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
public static class UplayLibrary
|
||||
public class UplayLibrary : GameLibrary
|
||||
{
|
||||
|
||||
|
||||
#region Class Variables
|
||||
// Static members are 'eagerly initialized', that is,
|
||||
// immediately when class is loaded for the first time.
|
||||
// .NET guarantees thread safety for static initialization
|
||||
private static readonly UplayLibrary _instance = new UplayLibrary();
|
||||
|
||||
// Common items to the class
|
||||
private static List<Game> _allUplayGames = new List<Game>();
|
||||
private static string uplayAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private static bool _isUplayInstalled = false;
|
||||
private static string _uplayExe;
|
||||
private static string _uplayPath;
|
||||
//private static string _uplayConfigVdfFile;
|
||||
internal static string registryUplayLauncherKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher";
|
||||
internal static string registryUplayInstallsKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs";
|
||||
internal static string registryUplayOpenCmdKey = @"SOFTWARE\Classes\uplay\Shell\Open\Command";
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private List<Game> _allGames = new List<Game>();
|
||||
private string uplayAppIdRegex = @"/^[0-9A-F]{1,10}$";
|
||||
private bool _isUplayInstalled = false;
|
||||
private string _uplayExe;
|
||||
private string _uplayPath;
|
||||
private List<string> _uplayProcessList = new List<string>() { "UbisoftGameLauncher", "UbisoftGameLauncher64" };
|
||||
//private string _uplayConfigVdfFile;
|
||||
internal string registryUplayLauncherKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher";
|
||||
internal string registryUplayInstallsKey = @"SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs";
|
||||
internal string registryUplayOpenCmdKey = @"SOFTWARE\Classes\uplay\Shell\Open\Command";
|
||||
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
// Other constants that are useful
|
||||
#endregion
|
||||
|
||||
private struct UplayAppInfo
|
||||
{
|
||||
public int GameID;
|
||||
public string GameName;
|
||||
public string GameExe;
|
||||
public string GameInstallDir;
|
||||
public string GameUplayIconPath;
|
||||
}
|
||||
|
||||
#region Class Constructors
|
||||
static UplayLibrary()
|
||||
static UplayLibrary() { }
|
||||
|
||||
private UplayLibrary()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -79,27 +82,43 @@ namespace DisplayMagician.GameLibraries
|
||||
#endregion
|
||||
|
||||
#region Class Properties
|
||||
public static List<Game> AllInstalledGames
|
||||
public override List<Game> AllInstalledGames
|
||||
{
|
||||
get
|
||||
{
|
||||
// Load the Uplay Games from Uplay Client if needed
|
||||
if (_allUplayGames.Count == 0)
|
||||
if (_allGames.Count == 0)
|
||||
LoadInstalledGames();
|
||||
return _allUplayGames;
|
||||
return _allGames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int InstalledUplayGameCount
|
||||
public override int InstalledGameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _allUplayGames.Count;
|
||||
return _allGames.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public static string UplayExe
|
||||
public override string GameLibraryName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Uplay";
|
||||
}
|
||||
}
|
||||
|
||||
public override SupportedGameLibraryType GameLibraryType
|
||||
{
|
||||
get
|
||||
{
|
||||
return SupportedGameLibraryType.Uplay;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GameLibraryExe
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -107,7 +126,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static string UplayPath
|
||||
public override string GameLibraryPath
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -115,7 +134,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUplayInstalled
|
||||
public override bool IsGameLibraryInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -124,33 +143,68 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public override bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Process> uplayLibraryProcesses = new List<Process>();
|
||||
|
||||
foreach (string uplayLibraryProcessName in _uplayProcessList)
|
||||
{
|
||||
// Look for the processes with the ProcessName we sorted out earlier
|
||||
uplayLibraryProcesses.AddRange(Process.GetProcessesByName(uplayLibraryProcessName));
|
||||
}
|
||||
|
||||
// If we have found one or more processes then we should be good to go
|
||||
// so let's break, and get to the next step....
|
||||
if (uplayLibraryProcesses.Count > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override List<string> GameLibraryProcesses
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uplayProcessList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
public static bool AddUplayGame(UplayGame uplayGame)
|
||||
public static UplayLibrary GetLibrary()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public override bool AddGame(Game uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
|
||||
// Doublecheck if it already exists
|
||||
// Because then we just update the one that already exists
|
||||
if (ContainsUplayGame(uplayGame))
|
||||
if (ContainsGame(uplayGame))
|
||||
{
|
||||
logger.Debug($"UplayLibrary/AddUplayGame: Updating Uplay game {uplayGame.Name} in our Uplay library");
|
||||
logger.Debug($"UplayLibrary/AddGame: Updating Uplay game {uplayGame.Name} in our Uplay library");
|
||||
// We update the existing Shortcut with the data over
|
||||
UplayGame uplayGameToUpdate = GetUplayGame(uplayGame.Id.ToString());
|
||||
UplayGame uplayGameToUpdate = (UplayGame)GetGame(uplayGame.Id.ToString());
|
||||
uplayGame.CopyTo(uplayGameToUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Debug($"UplayLibrary/AddUplayGame: Adding Uplay game {uplayGame.Name} to our Uplay library");
|
||||
logger.Debug($"UplayLibrary/AddGame: Adding Uplay game {uplayGame.Name} to our Uplay library");
|
||||
// Add the uplayGame to the list of uplayGames
|
||||
_allUplayGames.Add(uplayGame);
|
||||
_allGames.Add(uplayGame);
|
||||
}
|
||||
|
||||
//Doublecheck it's been added
|
||||
if (ContainsUplayGame(uplayGame))
|
||||
if (ContainsGame(uplayGame))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -159,76 +213,76 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool RemoveUplayGame(UplayGame uplayGame)
|
||||
public override bool RemoveGame(Game uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
if (!(uplayGame is Game))
|
||||
return false;
|
||||
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame: Removing Uplay game {uplayGame.Name} from our Uplay library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame: Removing Uplay game {uplayGame.Name} from our Uplay library");
|
||||
|
||||
// Remove the uplayGame from the list.
|
||||
int numRemoved = _allUplayGames.RemoveAll(item => item.Id.Equals(uplayGame.Id));
|
||||
int numRemoved = _allGames.RemoveAll(item => item.Id.Equals(uplayGame.Id));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame: Removed Uplay game with name {uplayGame.Name}");
|
||||
logger.Debug($"UplayLibrary/RemoveGame: Removed Uplay game with name {uplayGame.Name}");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame: Didn't remove Uplay game with ID {uplayGame.Name} from the Uplay Library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame: Didn't remove Uplay game with ID {uplayGame.Name} from the Uplay Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new UplayLibraryException();
|
||||
}
|
||||
|
||||
public static bool RemoveUplayGame(int uplayGameId)
|
||||
public override bool RemoveGameById(string uplayGameId)
|
||||
{
|
||||
if (uplayGameId<=0)
|
||||
if (uplayGameId.Equals(0))
|
||||
return false;
|
||||
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame2: Removing Uplay game with ID {uplayGameId} from the Uplay library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame2: Removing Uplay game with ID {uplayGameId} from the Uplay library");
|
||||
|
||||
// Remove the uplayGame from the list.
|
||||
int numRemoved = _allUplayGames.RemoveAll(item => item.Id.Equals(uplayGameId));
|
||||
int numRemoved = _allGames.RemoveAll(item => item.Id.Equals(uplayGameId));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame2: Removed Uplay game with ID {uplayGameId}");
|
||||
logger.Debug($"UplayLibrary/RemoveGame2: Removed Uplay game with ID {uplayGameId}");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame2: Didn't remove Uplay game with ID {uplayGameId} from the Uplay Library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame2: Didn't remove Uplay game with ID {uplayGameId} from the Uplay Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw new UplayLibraryException();
|
||||
}
|
||||
|
||||
public static bool RemoveUplayGame(string uplayGameNameOrUuid)
|
||||
public override bool RemoveGame(string uplayGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrId))
|
||||
return false;
|
||||
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame3: Removing Uplay game with Name or UUID {uplayGameNameOrUuid} from the Uplay library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame3: Removing Uplay game with Name or ID {uplayGameNameOrId} from the Uplay library");
|
||||
|
||||
int numRemoved;
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
Match match = Regex.Match(uplayGameNameOrId, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
numRemoved = _allUplayGames.RemoveAll(item => uplayGameNameOrUuid.Equals(Convert.ToUInt32(item.Id)));
|
||||
numRemoved = _allGames.RemoveAll(item => uplayGameNameOrId.Equals(item.Id));
|
||||
else
|
||||
numRemoved = _allUplayGames.RemoveAll(item => uplayGameNameOrUuid.Equals(item.Name));
|
||||
numRemoved = _allGames.RemoveAll(item => uplayGameNameOrId.Equals(item.Name));
|
||||
|
||||
if (numRemoved == 1)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame3: Removed Uplay game with Name or UUID {uplayGameNameOrUuid} ");
|
||||
logger.Debug($"UplayLibrary/RemoveGame3: Removed Uplay game with Name or UUID {uplayGameNameOrId} ");
|
||||
return true;
|
||||
}
|
||||
else if (numRemoved == 0)
|
||||
{
|
||||
logger.Debug($"UplayLibrary/RemoveUplayGame3: Didn't remove Uplay game with Name or UUID {uplayGameNameOrUuid} from the Uplay Library");
|
||||
logger.Debug($"UplayLibrary/RemoveGame3: Didn't remove Uplay game with Name or UUID {uplayGameNameOrId} from the Uplay Library");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -236,25 +290,25 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool ContainsUplayGame(UplayGame uplayGame)
|
||||
public override bool ContainsGame(Game uplayGame)
|
||||
{
|
||||
if (!(uplayGame is UplayGame))
|
||||
return false;
|
||||
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (testUplayGame.Id.Equals(uplayGame.Id))
|
||||
if (testGame.Id.Equals(uplayGame.Id))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ContainsUplayGame(int uplayGameId)
|
||||
public override bool ContainsGameById(string uplayGameId)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameId == testUplayGame.Id)
|
||||
if (uplayGameId == testGame.Id)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -263,27 +317,27 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static bool ContainsUplayGame(string uplayGameNameOrUuid)
|
||||
public override bool ContainsGame(string uplayGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrId))
|
||||
return false;
|
||||
|
||||
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
Match match = Regex.Match(uplayGameNameOrId, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(Convert.ToInt32(testUplayGame.Id)))
|
||||
if (uplayGameNameOrId.Equals(Convert.ToInt32(testGame.Id)))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(testUplayGame.Name))
|
||||
if (uplayGameNameOrId.Equals(testGame.Name))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -294,27 +348,27 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
|
||||
public static UplayGame GetUplayGame(string uplayGameNameOrUuid)
|
||||
public override Game GetGame(string uplayGameNameOrId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrUuid))
|
||||
if (String.IsNullOrWhiteSpace(uplayGameNameOrId))
|
||||
return null;
|
||||
|
||||
Match match = Regex.Match(uplayGameNameOrUuid, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
Match match = Regex.Match(uplayGameNameOrId, uplayAppIdRegex, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(Convert.ToInt32(testUplayGame.Id)))
|
||||
return testUplayGame;
|
||||
if (uplayGameNameOrId.Equals(Convert.ToInt32(testGame.Id)))
|
||||
return testGame;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameNameOrUuid.Equals(testUplayGame.Name))
|
||||
return testUplayGame;
|
||||
if (uplayGameNameOrId.Equals(testGame.Name))
|
||||
return testGame;
|
||||
}
|
||||
|
||||
}
|
||||
@ -323,19 +377,19 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
}
|
||||
|
||||
public static UplayGame GetUplayGame(int uplayGameId)
|
||||
public override Game GetGameById(string uplayGameId)
|
||||
{
|
||||
foreach (UplayGame testUplayGame in _allUplayGames)
|
||||
foreach (UplayGame testGame in _allGames)
|
||||
{
|
||||
if (uplayGameId == testUplayGame.Id)
|
||||
return testUplayGame;
|
||||
if (uplayGameId == testGame.Id)
|
||||
return testGame;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static bool LoadInstalledGames()
|
||||
public override bool LoadInstalledGames()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -462,7 +516,7 @@ namespace DisplayMagician.GameLibraries
|
||||
}
|
||||
|
||||
// for each game record grab:
|
||||
UplayAppInfo uplayGameAppInfo = new UplayAppInfo();
|
||||
GameAppInfo uplayGameAppInfo = new GameAppInfo();
|
||||
|
||||
// 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)
|
||||
@ -485,7 +539,7 @@ namespace DisplayMagician.GameLibraries
|
||||
// Stop this loop once we have both filname and gameid
|
||||
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}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: We got all the entries: gameFileName = {gameFileName } && gameId = {gameId } && gameIconPath = {uplayGameAppInfo.GameIconPath} && gameName = {uplayGameAppInfo.GameName}");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -516,8 +570,8 @@ namespace DisplayMagician.GameLibraries
|
||||
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 }");
|
||||
uplayGameAppInfo.GameIconPath = uplayGameIconPath;
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: Found uplayGameAppInfo.GameUplayIconPath = {uplayGameAppInfo.GameIconPath }");
|
||||
}
|
||||
gotGameIconPath = true;
|
||||
}
|
||||
@ -546,7 +600,7 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: gameId = {gameId}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: gameFileName = {gameFileName}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: gameGameIconPath = {uplayGameAppInfo.GameUplayIconPath}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: gameGameIconPath = {uplayGameAppInfo.GameIconPath}");
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: gameRegistryKey = {gameRegistryKey}");
|
||||
|
||||
if (gotGameRegistryKey)
|
||||
@ -575,9 +629,9 @@ namespace DisplayMagician.GameLibraries
|
||||
{
|
||||
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);
|
||||
uplayGameAppInfo.GameExePath = Path.Combine(uplayGameAppInfo.GameInstallDir, gameFileName);
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameAppInfo.GameExe = {uplayGameAppInfo.GameExePath}");
|
||||
uplayGameAppInfo.GameID = gameId;
|
||||
logger.Trace($"UplayLibrary/LoadInstalledGames: uplayGameAppInfo.GameID = {uplayGameAppInfo.GameID }");
|
||||
}
|
||||
else
|
||||
@ -587,14 +641,14 @@ namespace DisplayMagician.GameLibraries
|
||||
|
||||
// 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}");
|
||||
_allGames.Add(new UplayGame(uplayGameAppInfo.GameID, uplayGameAppInfo.GameName, uplayGameAppInfo.GameExePath, uplayGameAppInfo.GameIconPath));
|
||||
logger.Debug($"UplayLibrary/LoadInstalledGames: Adding Uplay Game with game id {uplayGameAppInfo.GameID}, name {uplayGameAppInfo.GameName}, game exe {uplayGameAppInfo.GameExePath} and icon path {uplayGameAppInfo.GameIconPath}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.Info($"UplayLibrary/LoadInstalledGames: Found {_allUplayGames.Count} installed Uplay games");
|
||||
logger.Info($"UplayLibrary/LoadInstalledGames: Found {_allGames.Count} installed Uplay games");
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,246 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,20 +10,15 @@ using DisplayMagician.InterProcess;
|
||||
using DisplayMagician.Resources;
|
||||
using DisplayMagicianShared;
|
||||
using DisplayMagician.UIForms;
|
||||
using DisplayMagician.GameLibraries;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Drawing;
|
||||
using DesktopNotifications;
|
||||
using System.Runtime.Serialization;
|
||||
using NLog.Config;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DisplayMagician {
|
||||
|
||||
public enum SupportedGameLibrary
|
||||
{
|
||||
Unknown,
|
||||
Steam,
|
||||
Uplay
|
||||
}
|
||||
|
||||
public enum ApplyProfileResult
|
||||
{
|
||||
@ -714,17 +709,18 @@ namespace DisplayMagician {
|
||||
Task loadSteamGamesTask = new Task(() =>
|
||||
{
|
||||
// Check if Steam is installed
|
||||
if (GameLibraries.SteamLibrary.IsSteamInstalled)
|
||||
GameLibrary steamLibrary = SteamLibrary.GetLibrary();
|
||||
if (steamLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Steam library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Steam Games");
|
||||
Console.Write("Loading Installed Steam Games...");
|
||||
if (!DisplayMagician.GameLibraries.SteamLibrary.LoadInstalledGames())
|
||||
if (!steamLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Steam Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Steam Games (found {GameLibraries.SteamLibrary.InstalledSteamGameCount})");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Steam Games (found {steamLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -737,17 +733,18 @@ namespace DisplayMagician {
|
||||
Task loadUplayGamesTask = new Task(() =>
|
||||
{
|
||||
// Check if Uplay is installed
|
||||
if (GameLibraries.UplayLibrary.IsUplayInstalled)
|
||||
GameLibrary uplayLibrary = SteamLibrary.GetLibrary();
|
||||
if (uplayLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Uplay library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Uplay Games");
|
||||
Console.Write("Loading Installed Uplay Games...");
|
||||
if (!DisplayMagician.GameLibraries.UplayLibrary.LoadInstalledGames())
|
||||
if (!uplayLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Uplay Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Uplay Games (found {GameLibraries.UplayLibrary.InstalledUplayGameCount})");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Uplay Games (found {uplayLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -757,45 +754,131 @@ namespace DisplayMagician {
|
||||
|
||||
});
|
||||
|
||||
// Store all the tasks in an array so we can wait on them later
|
||||
Task[] loadGamesTasks = new Task[2];
|
||||
loadGamesTasks[0] = loadSteamGamesTask;
|
||||
loadGamesTasks[1] = loadUplayGamesTask;
|
||||
// Now lets prepare loading all the Origin games we have installed
|
||||
Task loadOriginGamesTask = new Task(() =>
|
||||
{
|
||||
// Check if Origin is installed
|
||||
GameLibrary originLibrary = SteamLibrary.GetLibrary();
|
||||
if (originLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Origin library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Origin Games");
|
||||
Console.Write("Loading Installed Origin Games...");
|
||||
if (!originLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Origin Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Origin Games (found {originLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Origin not installed.");
|
||||
Console.WriteLine("Origin not installed.");
|
||||
}
|
||||
|
||||
logger.Debug($"Program/LoadGamesInBackground: Running game loading tasks.");
|
||||
// Go through and start all the tasks
|
||||
foreach (Task loadGameTask in loadGamesTasks)
|
||||
loadGameTask.Start();
|
||||
});
|
||||
|
||||
Action loadSteamGamesAction = new Action(() =>
|
||||
{
|
||||
// Check if Steam is installed
|
||||
GameLibrary steamLibrary = SteamLibrary.GetLibrary();
|
||||
if (steamLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Steam library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Steam Games");
|
||||
Console.Write("Loading Installed Steam Games...");
|
||||
if (!steamLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Steam Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Steam Games (found {steamLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Steam not installed.");
|
||||
Console.WriteLine("Steam not installed.");
|
||||
}
|
||||
});
|
||||
|
||||
// Now lets prepare loading all the Uplay games we have installed
|
||||
Action loadUplayGamesAction = new Action(() =>
|
||||
{
|
||||
// Check if Uplay is installed
|
||||
GameLibrary uplayLibrary = UplayLibrary.GetLibrary();
|
||||
if (uplayLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Uplay library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Uplay Games");
|
||||
Console.Write("Loading Installed Uplay Games...");
|
||||
if (!uplayLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Uplay Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Uplay Games (found {uplayLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Uplay not installed.");
|
||||
Console.WriteLine("Uplay not installed.");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Now lets prepare loading all the Origin games we have installed
|
||||
Action loadOriginGamesAction = new Action(() =>
|
||||
{
|
||||
// Check if Origin is installed
|
||||
GameLibrary originLibrary = OriginLibrary.GetLibrary();
|
||||
if (originLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
// Load Origin library games
|
||||
logger.Info($"Program/LoadGamesInBackground: Loading Installed Origin Games");
|
||||
Console.Write("Loading Installed Origin Games...");
|
||||
if (!originLibrary.LoadInstalledGames())
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Cannot load installed Origin Games!");
|
||||
}
|
||||
Console.WriteLine("Done.");
|
||||
logger.Info($"Program/LoadGamesInBackground: Loaded all Installed Origin Games (found {originLibrary.InstalledGameCount})");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"Program/LoadGamesInBackground: Origin not installed.");
|
||||
Console.WriteLine("Origin not installed.");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Store all the actions in a array so we can wait on them later
|
||||
List<Action> loadGamesActions = new List<Action>();
|
||||
loadGamesActions.Add(loadSteamGamesAction);
|
||||
loadGamesActions.Add(loadUplayGamesAction);
|
||||
loadGamesActions.Add(loadOriginGamesAction);
|
||||
|
||||
try
|
||||
{
|
||||
logger.Debug($"Program/LoadGamesInBackground: Waiting for all game loading tasks to finish");
|
||||
Task.WaitAll(loadGamesTasks);
|
||||
logger.Debug($"Program/LoadGamesInBackground: Running game loading actions.");
|
||||
// Go through and start all the actions, making sure we only have one threat per action to avoid thread issues
|
||||
int threads = loadGamesActions.Count;
|
||||
ParallelOptions options = new ParallelOptions { MaxDegreeOfParallelism = threads };
|
||||
Parallel.Invoke(options, loadGamesActions.ToArray());
|
||||
logger.Debug($"Program/LoadGamesInBackground: All game loading tasks finished");
|
||||
}
|
||||
catch (AggregateException ae)
|
||||
{
|
||||
logger.Error(ae, $"Program/LoadGamesInBackground exception during loadGamesTasks");
|
||||
Console.WriteLine("Program/LoadGamesInBackground : Task exception!");
|
||||
foreach (var e in ae.InnerExceptions)
|
||||
{
|
||||
// Handle the custom exception.
|
||||
if (e is LoadingInstalledGamesException)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
// Rethrow any other exception.
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
logger.Error(ae, $"Program/LoadGamesInBackground exception during loadGamesActions");
|
||||
}
|
||||
|
||||
bool failedTask = false;
|
||||
foreach (var loadGameTask in loadGamesTasks)
|
||||
|
||||
// TODO replicate this failed Task handling in Actions
|
||||
/*bool failedAction = false;
|
||||
foreach (var loadGameAction in loadGamesActions)
|
||||
{
|
||||
if (loadGameTask.Exception != null)
|
||||
if (loadGameAction. .Exception != null)
|
||||
{
|
||||
failedTask = true;
|
||||
foreach (var ex in loadGameTask.Exception.InnerExceptions)
|
||||
@ -804,7 +887,7 @@ namespace DisplayMagician {
|
||||
}
|
||||
|
||||
if (failedTask)
|
||||
return false;
|
||||
return false;*/
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -37,8 +37,8 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.4.0")]
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
@ -67,6 +67,8 @@ namespace DisplayMagician
|
||||
public int StartTimeout;
|
||||
public string GameArguments;
|
||||
public bool GameArgumentsRequired;
|
||||
public string DifferentGameExeToMonitor;
|
||||
public bool MonitorDifferentGameExe;
|
||||
}
|
||||
|
||||
public struct ShortcutError
|
||||
@ -89,12 +91,14 @@ namespace DisplayMagician
|
||||
private string _executableArguments;
|
||||
private bool _executableArgumentsRequired = false;
|
||||
private bool _processNameToMonitorUsesExecutable = true;
|
||||
private int _gameAppId;
|
||||
private string _gameAppId;
|
||||
private string _gameName;
|
||||
private SupportedGameLibrary _gameLibrary;
|
||||
private SupportedGameLibraryType _gameLibrary;
|
||||
private int _startTimeout = 20;
|
||||
private string _gameArguments;
|
||||
private bool _gameArgumentsRequired;
|
||||
private string _differentGameExeToMonitor;
|
||||
private bool _monitorDifferentGameExe = false;
|
||||
private string _audioDevice;
|
||||
private bool _changeAudioDevice;
|
||||
private bool _setAudioVolume = false;
|
||||
@ -126,9 +130,11 @@ namespace DisplayMagician
|
||||
_uuid = Guid.NewGuid().ToString("D");
|
||||
|
||||
// If there are no GameLibraries then choose executable instead
|
||||
if (!(UplayLibrary.IsUplayInstalled && SteamLibrary.IsSteamInstalled))
|
||||
if (!(UplayLibrary.GetLibrary().IsGameLibraryInstalled &&
|
||||
SteamLibrary.GetLibrary().IsGameLibraryInstalled &&
|
||||
OriginLibrary.GetLibrary().IsGameLibraryInstalled))
|
||||
{
|
||||
_gameLibrary = SupportedGameLibrary.Unknown;
|
||||
_gameLibrary = SupportedGameLibraryType.Unknown;
|
||||
_gameName = "";
|
||||
_gameArguments = "";
|
||||
_category = ShortcutCategory.Application;
|
||||
@ -278,12 +284,14 @@ namespace DisplayMagician
|
||||
#pragma warning disable CS3001 // Argument type is not CLS-compliant
|
||||
ProfileItem profile,
|
||||
#pragma warning restore CS3001 // Argument type is not CLS-compliant
|
||||
int gameAppId,
|
||||
string gameAppId,
|
||||
string gameName,
|
||||
SupportedGameLibrary gameLibrary,
|
||||
SupportedGameLibraryType gameLibrary,
|
||||
int gameTimeout,
|
||||
string gameArguments,
|
||||
bool gameArgumentsRequired,
|
||||
string differentGameExeToMonitor,
|
||||
bool monitorDifferentGameExe,
|
||||
ShortcutPermanence displayPermanence,
|
||||
ShortcutPermanence audioPermanence,
|
||||
ShortcutPermanence capturePermanence,
|
||||
@ -312,6 +320,8 @@ namespace DisplayMagician
|
||||
_startTimeout = gameTimeout;
|
||||
_gameArguments = gameArguments;
|
||||
_gameArgumentsRequired = gameArgumentsRequired;
|
||||
_differentGameExeToMonitor = differentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = monitorDifferentGameExe;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
_setAudioVolume = setAudioVolume;
|
||||
@ -377,6 +387,8 @@ namespace DisplayMagician
|
||||
_startTimeout = game.StartTimeout;
|
||||
_gameArguments = game.GameArguments;
|
||||
_gameArgumentsRequired = game.GameArgumentsRequired;
|
||||
_differentGameExeToMonitor = game.DifferentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = game.MonitorDifferentGameExe;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
_setAudioVolume = setAudioVolume;
|
||||
@ -440,6 +452,8 @@ namespace DisplayMagician
|
||||
_startTimeout = game.StartTimeout;
|
||||
_gameArguments = game.GameArguments;
|
||||
_gameArgumentsRequired = game.GameArgumentsRequired;
|
||||
_differentGameExeToMonitor = game.DifferentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = game.MonitorDifferentGameExe;
|
||||
_gameArgumentsRequired = false;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
@ -911,7 +925,7 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
public int GameAppId
|
||||
public string GameAppId
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -937,7 +951,7 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
public SupportedGameLibrary GameLibrary
|
||||
public SupportedGameLibraryType GameLibrary
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -989,6 +1003,33 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
public string DifferentGameExeToMonitor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _differentGameExeToMonitor;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_differentGameExeToMonitor = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MonitorDifferentGameExe
|
||||
{
|
||||
get
|
||||
{
|
||||
return _monitorDifferentGameExe;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_monitorDifferentGameExe = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string AudioDevice
|
||||
{
|
||||
get
|
||||
@ -1326,12 +1367,14 @@ namespace DisplayMagician
|
||||
#pragma warning disable CS3001 // Argument type is not CLS-compliant
|
||||
ProfileItem profile,
|
||||
#pragma warning restore CS3001 // Argument type is not CLS-compliant
|
||||
int gameAppId,
|
||||
string gameAppId,
|
||||
string gameName,
|
||||
SupportedGameLibrary gameLibrary,
|
||||
SupportedGameLibraryType gameLibrary,
|
||||
int gameTimeout,
|
||||
string gameArguments,
|
||||
bool gameArgumentsRequired,
|
||||
string differentGameExeToMonitor,
|
||||
bool monitorDifferentGameExe,
|
||||
ShortcutPermanence displayPermanence,
|
||||
ShortcutPermanence audioPermanence,
|
||||
ShortcutPermanence capturePermanence,
|
||||
@ -1360,6 +1403,8 @@ namespace DisplayMagician
|
||||
_startTimeout = gameTimeout;
|
||||
_gameArguments = gameArguments;
|
||||
_gameArgumentsRequired = gameArgumentsRequired;
|
||||
_differentGameExeToMonitor = differentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = monitorDifferentGameExe;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
_setAudioVolume = setAudioVolume;
|
||||
@ -1425,6 +1470,8 @@ namespace DisplayMagician
|
||||
_startTimeout = game.StartTimeout;
|
||||
_gameArguments = game.GameArguments;
|
||||
_gameArgumentsRequired = game.GameArgumentsRequired;
|
||||
_differentGameExeToMonitor = game.DifferentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = game.MonitorDifferentGameExe;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
_setAudioVolume = setAudioVolume;
|
||||
@ -1489,7 +1536,8 @@ namespace DisplayMagician
|
||||
_startTimeout = game.StartTimeout;
|
||||
_gameArguments = game.GameArguments;
|
||||
_gameArgumentsRequired = game.GameArgumentsRequired;
|
||||
_gameArgumentsRequired = false;
|
||||
_differentGameExeToMonitor = game.DifferentGameExeToMonitor;
|
||||
_monitorDifferentGameExe = game.MonitorDifferentGameExe;
|
||||
_changeAudioDevice = changeAudioDevice;
|
||||
_audioDevice = audioDevice;
|
||||
_setAudioVolume = setAudioVolume;
|
||||
@ -2014,12 +2062,13 @@ namespace DisplayMagician
|
||||
else if (Category.Equals(ShortcutCategory.Game))
|
||||
{
|
||||
// If the game is a Steam Game we check for that
|
||||
if (GameLibrary.Equals(SupportedGameLibrary.Steam))
|
||||
if (GameLibrary.Equals(SupportedGameLibraryType.Steam))
|
||||
{
|
||||
|
||||
SteamLibrary steamLibrary = SteamLibrary.GetLibrary();
|
||||
// First check if Steam is installed
|
||||
// Check if Steam is installed and error if it isn't
|
||||
if (!SteamLibrary.IsSteamInstalled)
|
||||
if (!steamLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "SteamNotInstalled";
|
||||
@ -2031,7 +2080,7 @@ namespace DisplayMagician
|
||||
}
|
||||
|
||||
// We need to look up details about the game
|
||||
if (!SteamLibrary.ContainsSteamGame(GameAppId))
|
||||
if (!steamLibrary.ContainsGameById(GameAppId))
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "SteamGameNotInstalled";
|
||||
@ -2043,11 +2092,12 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
else if (GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
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.IsUplayInstalled)
|
||||
if (!uplayLibrary.IsGameLibraryInstalled)
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "UplayNotInstalled";
|
||||
@ -2059,7 +2109,7 @@ namespace DisplayMagician
|
||||
}
|
||||
|
||||
// We need to look up details about the game
|
||||
if (!UplayLibrary.ContainsUplayGame(GameAppId))
|
||||
if (!uplayLibrary.ContainsGame(GameAppId))
|
||||
{
|
||||
ShortcutError error = new ShortcutError();
|
||||
error.Name = "UplayGameNotInstalled";
|
||||
|
@ -586,8 +586,8 @@ namespace DisplayMagician
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: We're already on the {rollbackProfile.Name} profile so no need to change profiles.");
|
||||
}
|
||||
// Tell the IPC Service we are busy right now, and keep the previous status for later
|
||||
InstanceStatus rollbackInstanceStatus = IPCService.GetInstance().Status;
|
||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||
//InstanceStatus rollbackInstanceStatus = IPCService.GetInstance().Status;
|
||||
//IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||
|
||||
// Only change profiles if we have to
|
||||
if (needToChangeProfiles)
|
||||
@ -769,7 +769,7 @@ namespace DisplayMagician
|
||||
}
|
||||
|
||||
// Set the IP Service status back to what it was
|
||||
IPCService.GetInstance().Status = rollbackInstanceStatus;
|
||||
//IPCService.GetInstance().Status = rollbackInstanceStatus;
|
||||
|
||||
// Now run the pre-start applications
|
||||
List<Process> startProgramsToStop = new List<Process>();
|
||||
@ -963,12 +963,12 @@ namespace DisplayMagician
|
||||
// make sure we have things to monitor and alert if not
|
||||
if (processesToMonitor.Count == 0)
|
||||
{
|
||||
logger.Error($"No '{processNameToLookFor}' processes found before waiting timeout. DisplayMagician was unable to find any processes before the {shortcutToUse.StartTimeout} second timeout");
|
||||
logger.Error($"ShortcutRepository/RunShortcut: No '{processNameToLookFor}' processes found before waiting timeout. DisplayMagician was unable to find any processes before the {shortcutToUse.StartTimeout} second timeout");
|
||||
}
|
||||
|
||||
// Store the process to monitor for later
|
||||
IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
//IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
|
||||
//IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
string notificationText = $"DisplayMagician: Running {shortcutToUse.ExecutableNameAndPath}...";
|
||||
@ -1002,7 +1002,6 @@ namespace DisplayMagician
|
||||
Thread.Sleep(2000);
|
||||
|
||||
// if we have things to monitor, then we should start to wait for them
|
||||
Console.WriteLine($"Waiting for all {processNameToLookFor} windows to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Waiting for application {processNameToLookFor} to exit.");
|
||||
if (processesToMonitor.Count > 0)
|
||||
{
|
||||
@ -1024,7 +1023,6 @@ namespace DisplayMagician
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"{processNameToLookFor} has exited.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Executable {processNameToLookFor} has exited.");
|
||||
|
||||
|
||||
@ -1050,109 +1048,123 @@ namespace DisplayMagician
|
||||
}
|
||||
else if (shortcutToUse.Category.Equals(ShortcutCategory.Game))
|
||||
{
|
||||
Game gameToRun = null;
|
||||
GameLibrary gameLibraryToUse = null;
|
||||
|
||||
// If the game is a Steam Game we check for that
|
||||
if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Steam))
|
||||
if (shortcutToUse.GameLibrary.Equals(SupportedGameLibraryType.Steam))
|
||||
{
|
||||
// We now need to get the SteamGame info
|
||||
SteamGame steamGameToRun = SteamLibrary.GetSteamGame(shortcutToUse.GameAppId);
|
||||
gameLibraryToUse = SteamLibrary.GetLibrary();
|
||||
}
|
||||
// If the game is a Uplay Uplay Game we check for that
|
||||
else if (shortcutToUse.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 (shortcutToUse.GameLibrary.Equals(SupportedGameLibraryType.Origin))
|
||||
{
|
||||
// We now need to get the Uplay Game info
|
||||
gameLibraryToUse = UplayLibrary.GetLibrary();
|
||||
}
|
||||
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Starting the {steamGameToRun.Name} Steam Game, and then we're going to monitor it to wait for it to close.");
|
||||
gameToRun = gameLibraryToUse.GetGameById(shortcutToUse.GameAppId);
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Starting the {gameToRun.Name} {gameLibraryToUse.GameLibraryName} Game, and then we're going to monitor it to wait for it to close.");
|
||||
|
||||
// If the GameAppID matches a Steam game, then lets run it
|
||||
if (steamGameToRun is SteamGame)
|
||||
// If the GameAppID is not null, then we've matched a game! Lets run it.
|
||||
if (gameToRun != null)
|
||||
{
|
||||
|
||||
// Now we want to tell the user we're start a game
|
||||
// Construct the Windows toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo($"notify=starting{gameLibraryToUse.GameLibraryName}", ToastActivationType.Foreground)
|
||||
.AddText($"Starting {gameLibraryToUse.GameLibraryName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for {gameLibraryToUse.GameLibraryName} Game Library to start (and update if needed)...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
Process gameProcess;
|
||||
if (gameToRun.StartMode.Equals(Game.GameStartMode.URI))
|
||||
{
|
||||
// Prepare to start the steam game using the URI interface
|
||||
// as used by Steam for it's own desktop shortcuts.
|
||||
var address = $"steam://rungameid/{steamGameToRun.Id}";
|
||||
|
||||
// Prepare to start the game using the URI method
|
||||
string address = "";
|
||||
if (shortcutToUse.GameArgumentsRequired)
|
||||
{
|
||||
address += "/" + shortcutToUse.GameArguments;
|
||||
address = gameToRun.GetStartURI(shortcutToUse.GameArguments);
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Shortcut has arguments: {shortcutToUse.GameArguments}");
|
||||
}
|
||||
logger.Debug($"ShortcutRepository/RunShortcut Steam launch address is {address}");
|
||||
// Start the URI Handler to run Steam
|
||||
Console.WriteLine($"Starting Steam Game: {steamGameToRun.Name}");
|
||||
var steamProcess = Process.Start(address);
|
||||
else
|
||||
{
|
||||
address = gameToRun.GetStartURI("");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Shortcut has no arguments");
|
||||
}
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Game launch URI is {address}");
|
||||
gameProcess = Process.Start(address);
|
||||
}
|
||||
|
||||
// Delay 500ms
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
|
||||
// Wait for GameLibrary to start
|
||||
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
|
||||
// so let's break, and get to the next step....
|
||||
if (gameLibraryToUse.IsRunning)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found at least one GameLibrary process has started");
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's wait a little while if we couldn't find
|
||||
// any processes yet
|
||||
Thread.Sleep(500);
|
||||
|
||||
// Wait for Steam game to update if needed
|
||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||
{
|
||||
}
|
||||
|
||||
if (!steamGameToRun.IsUpdating)
|
||||
{
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
// Delay 5secs
|
||||
Thread.Sleep(5000);
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Pausing to let the game library start the game.");
|
||||
|
||||
if (steamGameToRun.IsRunning)
|
||||
{
|
||||
logger.Info($"Found the '{steamGameToRun.Name}' process has started");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
|
||||
}
|
||||
|
||||
// Store the Steam Process ID for later
|
||||
IPCService.GetInstance().HoldProcessId = steamProcess?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
// Store the Process ID for later
|
||||
//IPCService.GetInstance().HoldProcessId = gameLibraryProcesses.FirstOrDefault()?.Id ?? 0;
|
||||
//IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// At this point, if the user wants to actually monitor a different process,
|
||||
// then we actually need to monitor that instead
|
||||
if (shortcutToUse.MonitorDifferentGameExe)
|
||||
{
|
||||
// If we are monitoring a different executable rather than the game itself, then lets get that name ready instead
|
||||
string altGameProcessToMonitor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.DifferentGameExeToMonitor);
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
if (steamGameToRun.Name.Length <= 41)
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name}...";
|
||||
if (gameToRun.Name.Length <= 41)
|
||||
notifyIcon.Text = $"DisplayMagician: Running {gameToRun.Name}...";
|
||||
else
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name.Substring(0, 41)}...";
|
||||
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
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=runningSteamGame", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the Steam Game {shortcutToUse.GameName} to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var 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 5 seconds for the game process to spawn
|
||||
Thread.Sleep(5000);
|
||||
// Wait for the game to exit
|
||||
Console.WriteLine($"Waiting for {steamGameToRun.Name} to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Waiting for Steam Game {steamGameToRun.Name} to exit.");
|
||||
while (true)
|
||||
{
|
||||
if (!steamGameToRun.IsRunning)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Steam Game {steamGameToRun.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);
|
||||
}
|
||||
Console.WriteLine($"{steamGameToRun.Name} has exited.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Steam Game {steamGameToRun.Name} has exited.");
|
||||
|
||||
// Tell the user that the Steam 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 shutdown and changes were reverted.");
|
||||
.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();
|
||||
@ -1161,122 +1173,94 @@ namespace DisplayMagician
|
||||
toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
else if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
{
|
||||
// We now need to get the Uplay Game info
|
||||
UplayGame uplayGameToRun = UplayLibrary.GetUplayGame(shortcutToUse.GameAppId);
|
||||
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Starting the {uplayGameToRun.Name} Uplay Game, and then we're going to monitor it to wait for it to close.");
|
||||
|
||||
// If the GameAppID matches a Uplay game, then lets run it
|
||||
if (uplayGameToRun is UplayGame)
|
||||
{
|
||||
// Prepare to start the Uplay game using the URI interface
|
||||
// as used by Uplay for it's own desktop shortcuts.
|
||||
var address = $"uplay://launch/{uplayGameToRun.Id}";
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Uplay launch address is {address}");
|
||||
if (shortcutToUse.GameArgumentsRequired)
|
||||
{
|
||||
address += "/" + shortcutToUse.GameArguments;
|
||||
}
|
||||
else
|
||||
{
|
||||
address += "/0";
|
||||
}
|
||||
|
||||
// Now we want to tell the user we're starting upc.exe
|
||||
// Construct the Windows toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=startingUplay", ToastActivationType.Foreground)
|
||||
.AddText($"Starting Uplay", hintMaxLines: 1)
|
||||
.AddText($"Waiting for Uplay to start (and update if needed)...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
|
||||
// Start the URI Handler to run Uplay
|
||||
Console.WriteLine($"Starting Uplay Game: {uplayGameToRun.Name}");
|
||||
logger.Info($"ShortcutRepository/RunShortcut: Starting Uplay Game: {uplayGameToRun.Name}");
|
||||
Process uplayStartProcess = Process.Start(address);
|
||||
|
||||
// Wait for Uplay to start
|
||||
List<Process> uplayProcesses = null;
|
||||
// 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)
|
||||
{
|
||||
|
||||
// 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());
|
||||
// Look for the processes with the ProcessName we sorted out earlier
|
||||
processesToMonitor = Process.GetProcessesByName(altGameProcessToMonitor).ToList();
|
||||
|
||||
// If we have found one or more processes then we should be good to go
|
||||
// so let's break
|
||||
if (uplayProcesses.Count > 0)
|
||||
if (processesToMonitor.Count > 0)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found {uplayProcesses.Count} 'UplayGameLauncher' processes have started");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found {processesToMonitor.Count} '{altGameProcessToMonitor}' processes to monitor");
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's wait a little while if we couldn't find
|
||||
// any processes yet
|
||||
Thread.Sleep(500);
|
||||
|
||||
}
|
||||
|
||||
//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)
|
||||
// make sure we have things to monitor and alert if not
|
||||
if (processesToMonitor.Count == 0)
|
||||
{
|
||||
|
||||
if (uplayGameToRun.IsRunning)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{uplayGameToRun.Name}' process has started");
|
||||
break;
|
||||
}
|
||||
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// Store the Uplay Process ID for later
|
||||
IPCService.GetInstance().HoldProcessId = uplayStartProcess?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
// 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)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {processesToMonitor.Count} Alternative Game Executable '{altGameProcessToMonitor}' processes are still running");
|
||||
while (true)
|
||||
{
|
||||
processesToMonitor = Process.GetProcessesByName(altGameProcessToMonitor).ToList();
|
||||
|
||||
// If we have no more processes left then we're done!
|
||||
if (processesToMonitor.Count == 0)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: No more '{altGameProcessToMonitor}' processes are still running");
|
||||
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: Alternative Game Executable {altGameProcessToMonitor} has exited.");
|
||||
|
||||
// Tell the user that the Alt Game Executable has closed
|
||||
// Construct the toast content
|
||||
tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=stopDetected", ToastActivationType.Foreground)
|
||||
.AddText($"{altGameProcessToMonitor} was closed", hintMaxLines: 1)
|
||||
.AddText($"{altGameProcessToMonitor} alternative game executable 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 are monitoring the game thats actually running (the most common scenario)
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
if (uplayGameToRun.Name.Length <= 41)
|
||||
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name}...";
|
||||
if (gameToRun.Name.Length <= 41)
|
||||
notifyIcon.Text = $"DisplayMagician: Running {gameToRun.Name}...";
|
||||
else
|
||||
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name.Substring(0, 41)}...";
|
||||
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=runningUplayGame", ToastActivationType.Foreground)
|
||||
.AddToastActivationInfo($"notify=running{gameLibraryToUse.GameLibraryName}Game", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName}", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the Uplay Game {shortcutToUse.GameName} to exit...");
|
||||
.AddText($"Waiting for the {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
@ -1289,17 +1273,35 @@ namespace DisplayMagician
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Wait 5 seconds for the game process to spawn
|
||||
Thread.Sleep(5000);
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
||||
if (gameToRun.IsRunning)
|
||||
{
|
||||
// The game is running! So now we continue processing
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{gameToRun.Name}' process has started");
|
||||
break;
|
||||
}
|
||||
|
||||
// Delay 500ms
|
||||
Thread.Sleep(500);
|
||||
|
||||
}
|
||||
|
||||
// Wait 5 more seconds for the game process to spawn
|
||||
// Thread.Sleep(5000);
|
||||
|
||||
// This is the main waiting thread!
|
||||
// Wait for the game to exit
|
||||
Console.WriteLine($"Waiting for {uplayGameToRun.Name} to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: waiting for Uplay Game {uplayGameToRun.Name} to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: waiting for {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} to exit.");
|
||||
while (true)
|
||||
{
|
||||
if (!uplayGameToRun.IsRunning)
|
||||
if (!gameToRun.IsRunning)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Uplay Game {uplayGameToRun.Name} is no longer running (IsRunning is false).");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} is no longer running (IsRunning is false).");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1308,15 +1310,15 @@ namespace DisplayMagician
|
||||
System.Threading.Thread.CurrentThread.Join(0);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
Console.WriteLine($"{uplayGameToRun.Name} has exited.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Uplay Game {uplayGameToRun.Name} has exited.");
|
||||
Console.WriteLine($"{gameToRun.Name} has exited.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: {gameLibraryToUse.GameLibraryName} Game {gameToRun.Name} has exited.");
|
||||
|
||||
// Tell the user that the Uplay Game has closed
|
||||
// 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 shutdown and changes were reverted.");
|
||||
.AddText($"{shortcutToUse.GameName} game was exited.");
|
||||
toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
doc = new XmlDocument();
|
||||
@ -1327,12 +1329,18 @@ 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.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Remove the status notification icon from the status area
|
||||
// once we've exited the game, but only if its a game or app
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Changing the system tray icon message back to what it was.");
|
||||
@ -1429,7 +1437,7 @@ namespace DisplayMagician
|
||||
// Change Audio Device back (if one specified)
|
||||
if (activeAudioDevices.Count > 0)
|
||||
{
|
||||
if (needToChangeAudioDevice)
|
||||
if (needToChangeAudioDevice && shortcutToUse.AudioPermanence == ShortcutPermanence.Temporary)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Reverting default audio back to {rollbackAudioDevice.Name} audio device");
|
||||
// use the Audio Device
|
||||
@ -1460,7 +1468,7 @@ namespace DisplayMagician
|
||||
// Change Capture Device back (if one specified)
|
||||
if (activeCaptureDevices.Count > 0)
|
||||
{
|
||||
if (needToChangeCaptureDevice)
|
||||
if (needToChangeCaptureDevice && shortcutToUse.CapturePermanence == ShortcutPermanence.Temporary)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Reverting default capture (microphone) device back to {rollbackCaptureDevice.Name} capture device");
|
||||
// use the Audio Device
|
||||
@ -1489,7 +1497,8 @@ namespace DisplayMagician
|
||||
}
|
||||
|
||||
// Change back to the original profile only if it is different
|
||||
if (needToChangeProfiles)
|
||||
// And if we're temporary
|
||||
if (needToChangeProfiles && shortcutToUse.DisplayPermanence == ShortcutPermanence.Temporary)
|
||||
{
|
||||
logger.Debug($"ShortcutRepository/RunShortcut: Rolling back display profile to {rollbackProfile.Name}");
|
||||
|
||||
@ -1532,3 +1541,4 @@ namespace DisplayMagician
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
1
DisplayMagician/UIForms/MainForm.Designer.cs
generated
1
DisplayMagician/UIForms/MainForm.Designer.cs
generated
@ -190,6 +190,7 @@
|
||||
//
|
||||
resources.ApplyResources(this.notifyIcon, "notifyIcon");
|
||||
this.notifyIcon.ContextMenuStrip = this.mainContextMenuStrip;
|
||||
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick);
|
||||
//
|
||||
// mainContextMenuStrip
|
||||
//
|
||||
|
@ -68,6 +68,14 @@ namespace DisplayMagician.UIForms
|
||||
allowVisible = true;
|
||||
// Really close the application when the form is closed
|
||||
allowClose = true;
|
||||
}
|
||||
|
||||
if (Program.AppProgramSettings.MinimiseOnStart && Program.AppProgramSettings.StartOnBootUp)
|
||||
{
|
||||
cb_minimise_notification_area.Checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cb_minimise_notification_area.Checked = false;
|
||||
}
|
||||
|
||||
@ -320,6 +328,7 @@ namespace DisplayMagician.UIForms
|
||||
allowClose = false;
|
||||
// Enable the MinimiseOnStart setting
|
||||
Program.AppProgramSettings.MinimiseOnStart = true;
|
||||
Program.AppProgramSettings.StartOnBootUp = true;
|
||||
// Change the exit_button text to say 'Close'
|
||||
btn_exit.Text = "&Close";
|
||||
}
|
||||
@ -331,6 +340,7 @@ namespace DisplayMagician.UIForms
|
||||
allowClose = true;
|
||||
// Disable the MinimiseOnStart setting
|
||||
Program.AppProgramSettings.MinimiseOnStart = false;
|
||||
Program.AppProgramSettings.StartOnBootUp = false;
|
||||
// Change the exit_button text to say 'Exit'
|
||||
btn_exit.Text = "&Exit";
|
||||
|
||||
@ -475,5 +485,10 @@ namespace DisplayMagician.UIForms
|
||||
string targetURL = @"https://github.com/sponsors/terrymacdonald";
|
||||
System.Diagnostics.Process.Start(targetURL);
|
||||
}
|
||||
|
||||
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
openApplicationWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10837,7 +10837,7 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="lbl_create_shortcut.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>282, 245</value>
|
||||
<value>282, 247</value>
|
||||
</data>
|
||||
<data name="lbl_create_shortcut.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>222, 22</value>
|
||||
@ -10879,16 +10879,16 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>234, 353</value>
|
||||
<value>162, 356</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>332, 20</value>
|
||||
<value>460, 20</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.Text" xml:space="preserve">
|
||||
<value>Start DisplayMagician minimised in notification area</value>
|
||||
<value>Start DisplayMagician minimised in notification area when computer starts</value>
|
||||
</data>
|
||||
<data name=">>cb_minimise_notification_area.Name" xml:space="preserve">
|
||||
<value>cb_minimise_notification_area</value>
|
||||
@ -10912,7 +10912,7 @@
|
||||
<value>Microsoft Sans Serif, 9.75pt</value>
|
||||
</data>
|
||||
<data name="lbl_version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 354</value>
|
||||
<value>12, 357</value>
|
||||
</data>
|
||||
<data name="lbl_version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>25, 16</value>
|
||||
@ -10948,7 +10948,7 @@
|
||||
<value>Microsoft Sans Serif, 21.75pt</value>
|
||||
</data>
|
||||
<data name="btn_setup_game_shortcuts.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>212, 172</value>
|
||||
<value>212, 174</value>
|
||||
</data>
|
||||
<data name="btn_setup_game_shortcuts.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>360, 50</value>
|
||||
@ -10981,7 +10981,7 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="btn_exit.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>700, 350</value>
|
||||
<value>700, 353</value>
|
||||
</data>
|
||||
<data name="btn_exit.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>75, 23</value>
|
||||
|
145
DisplayMagician/UIForms/ShortcutForm.Designer.cs
generated
145
DisplayMagician/UIForms/ShortcutForm.Designer.cs
generated
@ -44,6 +44,9 @@ namespace DisplayMagician.UIForms
|
||||
this.ilv_saved_profiles = new Manina.Windows.Forms.ImageListView();
|
||||
this.dv_profile = new DisplayMagicianShared.UserControls.DisplayView();
|
||||
this.tabp_audio = new System.Windows.Forms.TabPage();
|
||||
this.lbl_no_active_capture_devices = new System.Windows.Forms.Label();
|
||||
this.lbl_no_active_audio_devices = new System.Windows.Forms.Label();
|
||||
this.lbl_disabled_shortcut_audio_chipset = new System.Windows.Forms.Label();
|
||||
this.gb_capture_settings = new System.Windows.Forms.GroupBox();
|
||||
this.gb_capture_volume = new System.Windows.Forms.GroupBox();
|
||||
this.rb_set_capture_volume = new System.Windows.Forms.RadioButton();
|
||||
@ -118,6 +121,8 @@ namespace DisplayMagician.UIForms
|
||||
this.rb_standalone = new System.Windows.Forms.RadioButton();
|
||||
this.rb_no_game = new System.Windows.Forms.RadioButton();
|
||||
this.p_game = new System.Windows.Forms.Panel();
|
||||
this.btn_choose_alternative_game = new System.Windows.Forms.Button();
|
||||
this.txt_alternative_game = new System.Windows.Forms.TextBox();
|
||||
this.txt_game_launcher = new System.Windows.Forms.TextBox();
|
||||
this.txt_game_name = new System.Windows.Forms.TextBox();
|
||||
this.lbl_game_library = new System.Windows.Forms.Label();
|
||||
@ -146,9 +151,7 @@ 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.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.cb_wait_alternative_game = new System.Windows.Forms.CheckBox();
|
||||
this.tabc_shortcut.SuspendLayout();
|
||||
this.tabp_display.SuspendLayout();
|
||||
this.tabp_audio.SuspendLayout();
|
||||
@ -336,6 +339,56 @@ namespace DisplayMagician.UIForms
|
||||
this.tabp_audio.TabIndex = 4;
|
||||
this.tabp_audio.Text = "2. Choose Audio";
|
||||
//
|
||||
// lbl_no_active_capture_devices
|
||||
//
|
||||
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;
|
||||
//
|
||||
// lbl_no_active_audio_devices
|
||||
//
|
||||
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;
|
||||
//
|
||||
// lbl_disabled_shortcut_audio_chipset
|
||||
//
|
||||
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;
|
||||
//
|
||||
// gb_capture_settings
|
||||
//
|
||||
this.gb_capture_settings.Controls.Add(this.gb_capture_volume);
|
||||
@ -1236,6 +1289,9 @@ namespace DisplayMagician.UIForms
|
||||
//
|
||||
// p_game
|
||||
//
|
||||
this.p_game.Controls.Add(this.cb_wait_alternative_game);
|
||||
this.p_game.Controls.Add(this.btn_choose_alternative_game);
|
||||
this.p_game.Controls.Add(this.txt_alternative_game);
|
||||
this.p_game.Controls.Add(this.txt_game_launcher);
|
||||
this.p_game.Controls.Add(this.txt_game_name);
|
||||
this.p_game.Controls.Add(this.lbl_game_library);
|
||||
@ -1252,6 +1308,27 @@ namespace DisplayMagician.UIForms
|
||||
this.p_game.Size = new System.Drawing.Size(1006, 278);
|
||||
this.p_game.TabIndex = 7;
|
||||
//
|
||||
// btn_choose_alternative_game
|
||||
//
|
||||
this.btn_choose_alternative_game.Enabled = false;
|
||||
this.btn_choose_alternative_game.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btn_choose_alternative_game.ForeColor = System.Drawing.Color.White;
|
||||
this.btn_choose_alternative_game.Location = new System.Drawing.Point(878, 224);
|
||||
this.btn_choose_alternative_game.Name = "btn_choose_alternative_game";
|
||||
this.btn_choose_alternative_game.Size = new System.Drawing.Size(85, 27);
|
||||
this.btn_choose_alternative_game.TabIndex = 26;
|
||||
this.btn_choose_alternative_game.Text = "Choose";
|
||||
this.btn_choose_alternative_game.UseVisualStyleBackColor = true;
|
||||
this.btn_choose_alternative_game.Click += new System.EventHandler(this.btn_choose_alternative_game_Click);
|
||||
//
|
||||
// txt_alternative_game
|
||||
//
|
||||
this.txt_alternative_game.Enabled = false;
|
||||
this.txt_alternative_game.Location = new System.Drawing.Point(667, 225);
|
||||
this.txt_alternative_game.Name = "txt_alternative_game";
|
||||
this.txt_alternative_game.Size = new System.Drawing.Size(205, 26);
|
||||
this.txt_alternative_game.TabIndex = 24;
|
||||
//
|
||||
// txt_game_launcher
|
||||
//
|
||||
this.txt_game_launcher.Location = new System.Drawing.Point(605, 76);
|
||||
@ -1378,7 +1455,7 @@ namespace DisplayMagician.UIForms
|
||||
this.lv_games.LargeImageList = this.il_games;
|
||||
this.lv_games.Location = new System.Drawing.Point(23, 30);
|
||||
this.lv_games.Name = "lv_games";
|
||||
this.lv_games.Size = new System.Drawing.Size(338, 217);
|
||||
this.lv_games.Size = new System.Drawing.Size(338, 221);
|
||||
this.lv_games.SmallImageList = this.il_games;
|
||||
this.lv_games.TabIndex = 22;
|
||||
this.lv_games.UseCompatibleStateImageBehavior = false;
|
||||
@ -1583,55 +1660,16 @@ namespace DisplayMagician.UIForms
|
||||
this.cb_autosuggest.UseVisualStyleBackColor = true;
|
||||
this.cb_autosuggest.CheckedChanged += new System.EventHandler(this.cb_autosuggest_CheckedChanged);
|
||||
//
|
||||
// lbl_disabled_shortcut_audio_chipset
|
||||
// cb_wait_alternative_game
|
||||
//
|
||||
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;
|
||||
//
|
||||
// lbl_no_active_audio_devices
|
||||
//
|
||||
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;
|
||||
//
|
||||
// lbl_no_active_capture_devices
|
||||
//
|
||||
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;
|
||||
this.cb_wait_alternative_game.AutoSize = true;
|
||||
this.cb_wait_alternative_game.Location = new System.Drawing.Point(451, 214);
|
||||
this.cb_wait_alternative_game.Name = "cb_wait_alternative_game";
|
||||
this.cb_wait_alternative_game.Size = new System.Drawing.Size(220, 44);
|
||||
this.cb_wait_alternative_game.TabIndex = 27;
|
||||
this.cb_wait_alternative_game.Text = "Wait until this executable \r\nis closed before continuing:";
|
||||
this.cb_wait_alternative_game.UseVisualStyleBackColor = true;
|
||||
this.cb_wait_alternative_game.CheckedChanged += new System.EventHandler(this.cb_wait_alternative_game_CheckedChanged);
|
||||
//
|
||||
// ShortcutForm
|
||||
//
|
||||
@ -1819,5 +1857,8 @@ namespace DisplayMagician.UIForms
|
||||
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;
|
||||
private System.Windows.Forms.Button btn_choose_alternative_game;
|
||||
private System.Windows.Forms.TextBox txt_alternative_game;
|
||||
private System.Windows.Forms.CheckBox cb_wait_alternative_game;
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ namespace DisplayMagician.UIForms
|
||||
private bool _isUnsaved = true;
|
||||
private bool _loadedShortcut = false;
|
||||
private bool _autoName = true;
|
||||
private int _gameId = 0;
|
||||
private string _gameId = "0";
|
||||
private string _uuid = "";
|
||||
private CoreAudioController audioController = null;
|
||||
private List<CoreAudioDevice> audioDevices = null;
|
||||
@ -96,34 +96,42 @@ namespace DisplayMagician.UIForms
|
||||
}
|
||||
|
||||
|
||||
public SupportedGameLibrary GameLibrary
|
||||
public SupportedGameLibraryType GameLibrary
|
||||
{
|
||||
get
|
||||
{
|
||||
if (txt_game_launcher.Text.Contains("Steam"))
|
||||
{
|
||||
return SupportedGameLibrary.Steam;
|
||||
return SupportedGameLibraryType.Steam;
|
||||
}
|
||||
else if (txt_game_launcher.Text.Contains("Uplay"))
|
||||
{
|
||||
return SupportedGameLibrary.Uplay;
|
||||
return SupportedGameLibraryType.Uplay;
|
||||
}
|
||||
else if (txt_game_launcher.Text.Contains("Origin"))
|
||||
{
|
||||
return SupportedGameLibraryType.Origin;
|
||||
}
|
||||
|
||||
return SupportedGameLibrary.Unknown;
|
||||
return SupportedGameLibraryType.Unknown;
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SupportedGameLibrary.Steam:
|
||||
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibrary), SupportedGameLibrary.Steam);
|
||||
case SupportedGameLibraryType.Steam:
|
||||
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibraryType), SupportedGameLibraryType.Steam);
|
||||
break;
|
||||
|
||||
case SupportedGameLibrary.Uplay:
|
||||
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibrary), SupportedGameLibrary.Uplay);
|
||||
case SupportedGameLibraryType.Uplay:
|
||||
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibraryType), SupportedGameLibraryType.Uplay);
|
||||
break;
|
||||
|
||||
case SupportedGameLibrary.Unknown:
|
||||
case SupportedGameLibraryType.Origin:
|
||||
txt_game_launcher.Text = Enum.GetName(typeof(SupportedGameLibraryType), SupportedGameLibraryType.Origin);
|
||||
break;
|
||||
|
||||
case SupportedGameLibraryType.Unknown:
|
||||
txt_game_launcher.Text = "No supported Game Libraries found";
|
||||
break;
|
||||
|
||||
@ -269,7 +277,7 @@ namespace DisplayMagician.UIForms
|
||||
return;
|
||||
}
|
||||
|
||||
if (_gameId == 0)
|
||||
if (_gameId.Equals("0"))
|
||||
{
|
||||
MessageBox.Show(
|
||||
@"Please choose a Game by scrolling through the list, selecting the Game that you want, and then clicking the '>>' button to fill the Game fields.",
|
||||
@ -300,6 +308,26 @@ namespace DisplayMagician.UIForms
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_wait_alternative_game.Checked && String.IsNullOrWhiteSpace(txt_alternative_game.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"If you want to wait for an alternative game executable then you need to choose it! Click the 'Choose' button next to the different game executable field.",
|
||||
@"Need to choose the different game executable",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Exclamation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_wait_alternative_game.Checked && !File.Exists(txt_alternative_game.Text))
|
||||
{
|
||||
MessageBox.Show(
|
||||
@"The alternative game executable you have chosen does not exist! Please reselect the alternative game executable, or check you have permissions to view it.",
|
||||
@"Alternative game executable doesn't exist",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Exclamation);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -475,76 +503,58 @@ namespace DisplayMagician.UIForms
|
||||
if (rb_launcher.Checked)
|
||||
{
|
||||
logger.Trace($"ShortcutForm/btn_save_Click: We're saving a game!");
|
||||
|
||||
_gameToUse = new GameStruct
|
||||
{
|
||||
StartTimeout = Convert.ToInt32(nud_timeout_game.Value),
|
||||
GameArguments = txt_args_game.Text,
|
||||
GameArgumentsRequired = cb_args_game.Checked,
|
||||
DifferentGameExeToMonitor = txt_alternative_game.Text,
|
||||
MonitorDifferentGameExe = cb_wait_alternative_game.Checked
|
||||
};
|
||||
|
||||
// If the game is a SteamGame
|
||||
if (txt_game_launcher.Text == SupportedGameLibrary.Steam.ToString())
|
||||
if (txt_game_launcher.Text == SupportedGameLibraryType.Steam.ToString())
|
||||
{
|
||||
logger.Trace($"ShortcutForm/btn_save_Click: We're saving a Steam game!");
|
||||
// Find the SteamGame
|
||||
_gameToUse = new GameStruct
|
||||
{
|
||||
GameToPlay = (from steamGame in SteamLibrary.AllInstalledGames where steamGame.Id == _gameId select steamGame).First(),
|
||||
StartTimeout = Convert.ToInt32(nud_timeout_game.Value),
|
||||
GameArguments = txt_args_game.Text,
|
||||
GameArgumentsRequired = cb_args_game.Checked
|
||||
};
|
||||
|
||||
_shortcutToEdit.UpdateGameShortcut(
|
||||
txt_shortcut_save_name.Text,
|
||||
_profileToUse,
|
||||
_gameToUse,
|
||||
_displayPermanence,
|
||||
_audioPermanence,
|
||||
_capturePermanence,
|
||||
_gameToUse.GameToPlay.IconPath,
|
||||
_changeAudioDevice,
|
||||
_audioDevice,
|
||||
_setAudioVolume,
|
||||
_audioVolume,
|
||||
_changeCaptureDevice,
|
||||
_captureDevice,
|
||||
_setCaptureVolume,
|
||||
_captureVolume,
|
||||
_startPrograms,
|
||||
_autoName,
|
||||
_uuid
|
||||
);
|
||||
|
||||
_gameToUse.GameToPlay = (from steamGame in SteamLibrary.GetLibrary().AllInstalledGames where steamGame.Id == _gameId select steamGame).First();
|
||||
}
|
||||
// If the game is a SteamGame
|
||||
else if (txt_game_launcher.Text == SupportedGameLibrary.Uplay.ToString())
|
||||
// If the game is a UplayGame
|
||||
else if (txt_game_launcher.Text == SupportedGameLibraryType.Uplay.ToString())
|
||||
{
|
||||
logger.Trace($"ShortcutForm/btn_save_Click: We're saving a Uplay game!");
|
||||
// Find the UplayGame
|
||||
_gameToUse = new GameStruct
|
||||
{
|
||||
GameToPlay = (from uplayGame in UplayLibrary.AllInstalledGames where uplayGame.Id == _gameId select uplayGame).First(),
|
||||
StartTimeout = Convert.ToInt32(nud_timeout_game.Value),
|
||||
GameArguments = txt_args_game.Text,
|
||||
GameArgumentsRequired = cb_args_game.Checked
|
||||
};
|
||||
|
||||
_shortcutToEdit.UpdateGameShortcut(
|
||||
txt_shortcut_save_name.Text,
|
||||
_profileToUse,
|
||||
_gameToUse,
|
||||
_displayPermanence,
|
||||
_audioPermanence,
|
||||
_capturePermanence,
|
||||
_gameToUse.GameToPlay.IconPath,
|
||||
_changeAudioDevice,
|
||||
_audioDevice,
|
||||
_setAudioVolume,
|
||||
_audioVolume,
|
||||
_changeCaptureDevice,
|
||||
_captureDevice,
|
||||
_setCaptureVolume,
|
||||
_captureVolume,
|
||||
_startPrograms,
|
||||
_autoName,
|
||||
_uuid
|
||||
);
|
||||
|
||||
_gameToUse.GameToPlay = (from uplayGame in UplayLibrary.GetLibrary().AllInstalledGames where uplayGame.Id == _gameId select uplayGame).First();
|
||||
}
|
||||
// If the game is an Origin Game
|
||||
else if (txt_game_launcher.Text == SupportedGameLibraryType.Origin.ToString())
|
||||
{
|
||||
logger.Trace($"ShortcutForm/btn_save_Click: We're saving an Origin game!");
|
||||
_gameToUse.GameToPlay = (from originGame in OriginLibrary.GetLibrary().AllInstalledGames where originGame.Id == _gameId select originGame).First();
|
||||
}
|
||||
|
||||
_shortcutToEdit.UpdateGameShortcut(
|
||||
txt_shortcut_save_name.Text,
|
||||
_profileToUse,
|
||||
_gameToUse,
|
||||
_displayPermanence,
|
||||
_audioPermanence,
|
||||
_capturePermanence,
|
||||
_gameToUse.GameToPlay.IconPath,
|
||||
_changeAudioDevice,
|
||||
_audioDevice,
|
||||
_setAudioVolume,
|
||||
_audioVolume,
|
||||
_changeCaptureDevice,
|
||||
_captureDevice,
|
||||
_setCaptureVolume,
|
||||
_captureVolume,
|
||||
_startPrograms,
|
||||
_autoName,
|
||||
_uuid
|
||||
);
|
||||
}
|
||||
else if (rb_standalone.Checked)
|
||||
{
|
||||
@ -641,7 +651,7 @@ namespace DisplayMagician.UIForms
|
||||
if ((txt_shortcut_save_name.Text.Length > 0) &&
|
||||
_profileToUse is ProfileItem &&
|
||||
(rb_no_game.Checked ||
|
||||
rb_launcher.Checked && _gameId > 0 ||
|
||||
rb_launcher.Checked && !_gameId.Equals("0") ||
|
||||
rb_standalone.Checked && txt_executable.Text.Length > 0))
|
||||
return true;
|
||||
else
|
||||
@ -913,9 +923,11 @@ namespace DisplayMagician.UIForms
|
||||
// Populate a full list of games
|
||||
// Start with the Steam Games
|
||||
allGames = new List<Game>();
|
||||
allGames.AddRange(SteamLibrary.AllInstalledGames);
|
||||
allGames.AddRange(SteamLibrary.GetLibrary().AllInstalledGames);
|
||||
// Then add the Uplay Games
|
||||
allGames.AddRange(UplayLibrary.AllInstalledGames);
|
||||
allGames.AddRange(UplayLibrary.GetLibrary().AllInstalledGames);
|
||||
// Then add the Origin Games
|
||||
allGames.AddRange(OriginLibrary.GetLibrary().AllInstalledGames);
|
||||
|
||||
|
||||
// Load all the Games into the Games ListView
|
||||
@ -937,11 +949,6 @@ namespace DisplayMagician.UIForms
|
||||
// Add the images to the images array
|
||||
il_games.Images.Add(bm);
|
||||
|
||||
/*if (!Visible)
|
||||
{
|
||||
//return;
|
||||
}*/
|
||||
|
||||
// ADd the game to the game array
|
||||
lv_games.Items.Add(new ListViewItem
|
||||
{
|
||||
@ -1043,8 +1050,23 @@ namespace DisplayMagician.UIForms
|
||||
break;
|
||||
}
|
||||
|
||||
// Monitor the alternative game exe if we have it
|
||||
if (_shortcutToEdit.MonitorDifferentGameExe)
|
||||
{
|
||||
cb_wait_alternative_game.Checked = true;
|
||||
if (!String.IsNullOrWhiteSpace(_shortcutToEdit.DifferentGameExeToMonitor))
|
||||
{
|
||||
txt_alternative_game.Text = _shortcutToEdit.DifferentGameExeToMonitor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cb_wait_alternative_game.Checked = false;
|
||||
}
|
||||
|
||||
|
||||
// Set the launcher items if we have them
|
||||
if (_shortcutToEdit.GameLibrary.Equals(SupportedGameLibrary.Unknown))
|
||||
if (_shortcutToEdit.GameLibrary.Equals(SupportedGameLibraryType.Unknown))
|
||||
{
|
||||
if (allGames.Count <= 0)
|
||||
{
|
||||
@ -1063,7 +1085,6 @@ namespace DisplayMagician.UIForms
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
txt_game_launcher.Text = _shortcutToEdit.GameLibrary.ToString();
|
||||
@ -1286,7 +1307,8 @@ namespace DisplayMagician.UIForms
|
||||
{
|
||||
if (_loadedShortcut)
|
||||
_isUnsaved = true;
|
||||
if (File.Exists(dialog_open.FileName) && Path.GetExtension(dialog_open.FileName) == @".exe")
|
||||
string fileExt = Path.GetExtension(dialog_open.FileName);
|
||||
if (File.Exists(dialog_open.FileName) && (fileExt == @".exe" || fileExt == @".com"))
|
||||
{
|
||||
txt_alternative_executable.Text = dialog_open.FileName;
|
||||
dialog_open.FileName = string.Empty;
|
||||
@ -2164,5 +2186,44 @@ namespace DisplayMagician.UIForms
|
||||
else
|
||||
cb_start_program4.CheckState = CheckState.Unchecked;
|
||||
}
|
||||
|
||||
private void cb_wait_alternative_game_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_loadedShortcut)
|
||||
_isUnsaved = true;
|
||||
if (cb_wait_alternative_game.Checked)
|
||||
{
|
||||
txt_alternative_game.Enabled = true;
|
||||
btn_choose_alternative_game.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
txt_alternative_game.Enabled = false;
|
||||
btn_choose_alternative_game.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_choose_alternative_game_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (dialog_open.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
if (_loadedShortcut)
|
||||
_isUnsaved = true;
|
||||
string fileExt = Path.GetExtension(dialog_open.FileName);
|
||||
if (File.Exists(dialog_open.FileName) && (fileExt == @".exe" || fileExt == @".com"))
|
||||
{
|
||||
txt_alternative_game.Text = dialog_open.FileName;
|
||||
dialog_open.FileName = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(
|
||||
Language.Selected_file_is_not_a_valid_file,
|
||||
Language.Executable,
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.4.0")]
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
@ -6,7 +6,7 @@
|
||||
-->
|
||||
<?define MajorVersion="1" ?>
|
||||
<?define MinorVersion="0" ?>
|
||||
<?define BuildVersion="4" ?>
|
||||
<?define BuildVersion="5" ?>
|
||||
<!-- Revision is NOT used by WiX in the upgrade procedure -->
|
||||
<!-- Full version number to display -->
|
||||
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>
|
||||
|
@ -807,18 +807,80 @@ namespace DisplayMagicianShared
|
||||
NvAPIWrapper.Display.DisplayDevice aConnectedDisplayDevice = myPhysicalGPU.GetDisplayDeviceByOutput(aGPUOutput);
|
||||
|
||||
// Create an array of all the important display info we need to record
|
||||
string[] displayInfo = {
|
||||
"NVIDIA",
|
||||
myPhysicalGPU.ArchitectInformation.ShortName.ToString(),
|
||||
myPhysicalGPU.ArchitectInformation.Revision.ToString(),
|
||||
myPhysicalGPU.Board.ToString(),
|
||||
myPhysicalGPU.Foundry.ToString(),
|
||||
myPhysicalGPU.GPUId.ToString(),
|
||||
myPhysicalGPU.GPUType.ToString(),
|
||||
//aGPUOutput.OutputId.ToString(),
|
||||
aConnectedDisplayDevice.ConnectionType.ToString(),
|
||||
aConnectedDisplayDevice.DisplayId.ToString()
|
||||
};
|
||||
List<string> displayInfo = new List<string>();
|
||||
displayInfo.Add("NVIDIA");
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.ArchitectInformation.ShortName.ToString());
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex,$"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture ShortName from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.ArchitectInformation.Revision.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture Revision from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.Board.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Board details from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.Foundry.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Foundry from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.GPUId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUId from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.GPUType.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUType from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(aConnectedDisplayDevice.ConnectionType.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Connection from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(aConnectedDisplayDevice.DisplayId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA DisplayID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
|
||||
// Create a display identifier out of it
|
||||
string displayIdentifier = String.Join("|", displayInfo);
|
||||
@ -848,59 +910,129 @@ namespace DisplayMagicianShared
|
||||
PathDisplaySource pathDisplaySource = attachedDisplay.ToPathDisplaySource();
|
||||
PathDisplayTarget pathDisplayTarget = attachedDisplay.ToPathDisplayTarget();
|
||||
|
||||
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}");
|
||||
try
|
||||
{
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DP : {displayAdapter.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DN : {displayAdapter.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DDA : {displayAdapter.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception accessing one of the WindowsDisplayAPI items to print it out during a TRACE session");
|
||||
}
|
||||
|
||||
// Create an array of all the important display info we need to record
|
||||
string[] displayInfo = {
|
||||
"WINAPI",
|
||||
displayAdapter.DeviceName.ToString(),
|
||||
pathDisplayAdapter.AdapterId.ToString(),
|
||||
pathDisplayTarget.ConnectorInstance.ToString(),
|
||||
pathDisplayTarget.FriendlyName,
|
||||
pathDisplayTarget.EDIDManufactureCode.ToString(),
|
||||
pathDisplayTarget.EDIDManufactureId.ToString(),
|
||||
pathDisplayTarget.EDIDProductCode.ToString(),
|
||||
pathDisplayTarget.TargetId.ToString(),
|
||||
};
|
||||
List<string> displayInfo = new List<string>();
|
||||
displayInfo.Add("WINAPI");
|
||||
try
|
||||
{
|
||||
displayInfo.Add(displayAdapter.DeviceName.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter Device name from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayAdapter.AdapterId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.ConnectorInstance.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Connector Instance from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.FriendlyName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDManufactureCode.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDManufactureId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDProductCode.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.TargetId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
|
||||
// Create a display identifier out of it
|
||||
string displayIdentifier = String.Join("|", displayInfo);
|
||||
@ -954,18 +1086,80 @@ namespace DisplayMagicianShared
|
||||
if (aDisplayDevice.IsAvailable== true)
|
||||
{
|
||||
// Create an array of all the important display info we need to record
|
||||
string[] displayInfo = {
|
||||
"NVIDIA",
|
||||
myPhysicalGPU.ArchitectInformation.ShortName.ToString(),
|
||||
myPhysicalGPU.ArchitectInformation.Revision.ToString(),
|
||||
myPhysicalGPU.Board.ToString(),
|
||||
myPhysicalGPU.Foundry.ToString(),
|
||||
myPhysicalGPU.GPUId.ToString(),
|
||||
myPhysicalGPU.GPUType.ToString(),
|
||||
//aDisplayDevice.Output.OutputId.ToString(),
|
||||
aDisplayDevice.ConnectionType.ToString(),
|
||||
aDisplayDevice.DisplayId.ToString(),
|
||||
};
|
||||
List<string> displayInfo = new List<string>();
|
||||
displayInfo.Add("NVIDIA");
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.ArchitectInformation.ShortName.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture ShortName from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.ArchitectInformation.Revision.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Architecture Revision from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.Board.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Board details from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.Foundry.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Foundry from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.GPUId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUId from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(myPhysicalGPU.GPUType.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA GPUType from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(aDisplayDevice.ConnectionType.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA Connection from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(aDisplayDevice.DisplayId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting NVIDIA DisplayID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
|
||||
// Create a display identifier out of it
|
||||
string displayIdentifier = String.Join("|", displayInfo);
|
||||
@ -976,7 +1170,7 @@ namespace DisplayMagicianShared
|
||||
}
|
||||
}
|
||||
}
|
||||
// else videocard is not NVIdia so we just use the WindowsAPI access method
|
||||
// else videocard is not NVIDIA so we just use the WindowsAPI access method
|
||||
// Note: This won't support any special AMD EyeFinity profiles unfortunately.....
|
||||
// TODO: Add the detection and generation of the device ids using an AMD library
|
||||
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
||||
@ -997,59 +1191,129 @@ namespace DisplayMagicianShared
|
||||
PathDisplaySource pathDisplaySource = attachedDisplay.ToPathDisplaySource();
|
||||
PathDisplayTarget pathDisplayTarget = attachedDisplay.ToPathDisplayTarget();
|
||||
|
||||
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}");
|
||||
try
|
||||
{
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDN : {attachedDisplay.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDFN : {attachedDisplay.DisplayFullName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.DisplayName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIN : {attachedDisplay.IsAvailable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIGP : {attachedDisplay.IsGDIPrimary}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADDIV : {attachedDisplay.IsValid}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSCD : {attachedDisplay.CurrentSetting.ColorDepth}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSF : {attachedDisplay.CurrentSetting.Frequency}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSIE : {attachedDisplay.CurrentSetting.IsEnable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSII : {attachedDisplay.CurrentSetting.IsInterlaced}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSO : {attachedDisplay.CurrentSetting.Orientation}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSOSM : {attachedDisplay.CurrentSetting.OutputScalingMode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSP : {attachedDisplay.CurrentSetting.Position}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: ADCSR : {attachedDisplay.CurrentSetting.Resolution}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DP : {displayAdapter.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DN : {displayAdapter.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DK : {displayAdapter.DeviceKey}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: DDA : {displayAdapter.DeviceName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}");
|
||||
SharedLogger.logger.Trace($"ProfileRepository/GenerateProfileDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception accessing one of the WindowsDisplayAPI items to print it out during a TRACE session");
|
||||
}
|
||||
|
||||
// Create an array of all the important display info we need to record
|
||||
string[] displayInfo = {
|
||||
"WINAPI",
|
||||
displayAdapter.DeviceName.ToString(),
|
||||
pathDisplayAdapter.AdapterId.ToString(),
|
||||
pathDisplayTarget.ConnectorInstance.ToString(),
|
||||
pathDisplayTarget.FriendlyName,
|
||||
pathDisplayTarget.EDIDManufactureCode.ToString(),
|
||||
pathDisplayTarget.EDIDManufactureId.ToString(),
|
||||
pathDisplayTarget.EDIDProductCode.ToString(),
|
||||
pathDisplayTarget.TargetId.ToString(),
|
||||
};
|
||||
List<string> displayInfo = new List<string>();
|
||||
displayInfo.Add("WINAPI");
|
||||
try
|
||||
{
|
||||
displayInfo.Add(displayAdapter.DeviceName.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter Device name from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayAdapter.AdapterId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Adapter ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.ConnectorInstance.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Connector Instance from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.FriendlyName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target Friendly name from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDManufactureCode.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDManufactureId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Manufacturer ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.EDIDProductCode.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
try
|
||||
{
|
||||
displayInfo.Add(pathDisplayTarget.TargetId.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Warn(ex, $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception getting Windows Display Target ID from video card. Substituting with a # instead");
|
||||
displayInfo.Add("#");
|
||||
}
|
||||
|
||||
// Create a display identifier out of it
|
||||
string displayIdentifier = String.Join("|", displayInfo);
|
||||
|
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.4.0")]
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.4.0")]
|
||||
[assembly: AssemblyVersion("1.0.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.5.0")]
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "1.0.4.0",
|
||||
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.4/DisplayMagicianSetup-v1.0.4.msi",
|
||||
"version": "1.0.5.0",
|
||||
"url": "https://github.com/terrymacdonald/DisplayMagician/releases/download/v1.0.5/DisplayMagicianSetup-v1.0.5.msi",
|
||||
"changelog": "https://github.com/terrymacdonald/DisplayMagician/releases",
|
||||
"mandatory": {
|
||||
"value": false,
|
||||
@ -8,7 +8,7 @@
|
||||
"mode": 0
|
||||
},
|
||||
"checksum": {
|
||||
"value": "253E7B3BCC753AA7621BD88C7F86155B5CAF5C09C2DD222B25A3D4F3D819790E",
|
||||
"value": "36273CAEB4E7FE006ED48400CC243B0D01CE4AEFCF8F399A9641B7C124245F79",
|
||||
"hashingAlgorithm": "SHA256"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user