mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Added logging and improved readme
Added logging to ProfileRepository and ShortcutRepository
This commit is contained in:
parent
aece0cce29
commit
6b02e2ccbe
@ -372,7 +372,7 @@ namespace DisplayMagician
|
|||||||
private static bool LoadShortcuts()
|
private static bool LoadShortcuts()
|
||||||
{
|
{
|
||||||
|
|
||||||
logger.Debug($"ShortcutRepository/LoadShortcut: Loading shortcuts from {_shortcutStorageJsonFileName} into the Shortcut Repository");
|
logger.Debug($"ShortcutRepository/LoadShortcuts: Loading shortcuts from {_shortcutStorageJsonFileName} into the Shortcut Repository");
|
||||||
|
|
||||||
if (File.Exists(_shortcutStorageJsonFileName))
|
if (File.Exists(_shortcutStorageJsonFileName))
|
||||||
{
|
{
|
||||||
@ -395,14 +395,14 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex, $"ShortcutRepository/LoadShortcut: Tried to parse the JSON in the {_shortcutStorageJsonFileName} but the JsonConvert threw an exception.");
|
logger.Error(ex, $"ShortcutRepository/LoadShortcuts: Tried to parse the JSON in the {_shortcutStorageJsonFileName} but the JsonConvert threw an exception.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup all the Profile Names in the Saved Profiles
|
// Lookup all the Profile Names in the Saved Profiles
|
||||||
// and link the profiles to the Shortcuts as we only
|
// and link the profiles to the Shortcuts as we only
|
||||||
// store the profile names to allow users to uodate profiles
|
// store the profile names to allow users to uodate profiles
|
||||||
// separately from the shortcuts
|
// separately from the shortcuts
|
||||||
logger.Debug($"ShortcutRepository/LoadShortcut: Connecting Shortcut profile names to the real profile objects");
|
logger.Debug($"ShortcutRepository/LoadShortcuts: Connecting Shortcut profile names to the real profile objects");
|
||||||
foreach (ShortcutItem updatedShortcut in _allShortcuts)
|
foreach (ShortcutItem updatedShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
foreach (ProfileItem profile in ProfileRepository.AllProfiles)
|
foreach (ProfileItem profile in ProfileRepository.AllProfiles)
|
||||||
@ -418,7 +418,7 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We should only get here if there isn't a profile to match to.
|
// We should only get here if there isn't a profile to match to.
|
||||||
logger.Debug($"ShortcutRepository/LoadShortcut: Couldn't find the profile with UUID {updatedShortcut.ProfileUUID} so couldn't link it to a profile! We can't use this shortcut.");
|
logger.Debug($"ShortcutRepository/LoadShortcuts: Couldn't find the profile with UUID {updatedShortcut.ProfileUUID} so couldn't link it to a profile! We can't use this shortcut.");
|
||||||
updatedShortcut.ProfileToUse = null;
|
updatedShortcut.ProfileToUse = null;
|
||||||
updatedShortcut.IsPossible = false;
|
updatedShortcut.IsPossible = false;
|
||||||
}
|
}
|
||||||
@ -428,12 +428,12 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Debug($"ShortcutRepository/LoadShortcut: The {_shortcutStorageJsonFileName} shortcut JSON file exists but is empty! So we're going to treat it as if it didn't exist.");
|
logger.Debug($"ShortcutRepository/LoadShortcuts: The {_shortcutStorageJsonFileName} shortcut JSON file exists but is empty! So we're going to treat it as if it didn't exist.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Debug($"ShortcutRepository/LoadShortcut: Couldn't find the {_shortcutStorageJsonFileName} shortcut JSON file that contains the Shortcuts");
|
logger.Debug($"ShortcutRepository/LoadShortcuts: Couldn't find the {_shortcutStorageJsonFileName} shortcut JSON file that contains the Shortcuts");
|
||||||
}
|
}
|
||||||
_shortcutsLoaded = true;
|
_shortcutsLoaded = true;
|
||||||
return true;
|
return true;
|
||||||
@ -450,9 +450,21 @@ namespace DisplayMagician
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(AppShortcutStoragePath);
|
Directory.CreateDirectory(AppShortcutStoragePath);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (UnauthorizedAccessException ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex, $"ShortcutRepository/SaveShortcuts: Unable to create Shortcut folder {AppShortcutStoragePath}.");
|
logger.Fatal(ex, $"ShortcutRepository/SaveShortcuts: DisplayMagician doesn't have permissions to create the Shortcuts storage folder {AppShortcutStoragePath}.");
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
logger.Fatal(ex, $"ShortcutRepository/SaveShortcuts: DisplayMagician can't create the Shortcuts storage folder {AppShortcutStoragePath} due to an invalid argument.");
|
||||||
|
}
|
||||||
|
catch (PathTooLongException ex)
|
||||||
|
{
|
||||||
|
logger.Fatal(ex, $"ShortcutRepository/SaveShortcuts: DisplayMagician can't create the Shortcuts storage folder {AppShortcutStoragePath} as the path is too long.");
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException ex)
|
||||||
|
{
|
||||||
|
logger.Fatal(ex, $"ShortcutRepository/SaveShortcuts: DisplayMagician can't create the Shortcuts storage folder {AppShortcutStoragePath} as the parent folder isn't there.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -463,7 +475,7 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.Debug($"ShortcutRepository/SaveShortcuts: Creating the shortcut folder {AppShortcutStoragePath} as it doesn't currently exist.");
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Converting the objects to JSON format.");
|
||||||
|
|
||||||
var json = JsonConvert.SerializeObject(_allShortcuts, Formatting.Indented, new JsonSerializerSettings
|
var json = JsonConvert.SerializeObject(_allShortcuts, Formatting.Indented, new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
|
@ -543,6 +543,7 @@ namespace DisplayMagicianShared
|
|||||||
SharedLogger.logger.Error(ex, $"ProfileRepository/LoadProfiles: Tried to parse the JSON in the {_profileStorageJsonFileName} but the JsonConvert threw an exception.");
|
SharedLogger.logger.Error(ex, $"ProfileRepository/LoadProfiles: Tried to parse the JSON in the {_profileStorageJsonFileName} but the JsonConvert threw an exception.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ProfileItem myCurrentProfile = new ProfileItem
|
ProfileItem myCurrentProfile = new ProfileItem
|
||||||
{
|
{
|
||||||
Name = "Current Display Profile",
|
Name = "Current Display Profile",
|
||||||
@ -551,13 +552,11 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
_currentProfile = myCurrentProfile;
|
_currentProfile = myCurrentProfile;
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/LoadProfiles: Finding the current profile in the Profile Repository");
|
||||||
|
|
||||||
// Lookup all the Profile Names in the Saved Profiles
|
// Lookup all the Profile Names in the Saved Profiles
|
||||||
foreach (ProfileItem loadedProfile in _allProfiles)
|
foreach (ProfileItem loadedProfile in _allProfiles)
|
||||||
{
|
{
|
||||||
// Save a profile Icon to the profile
|
|
||||||
/* loadedProfile.ProfileIcon = new ProfileIcon(loadedProfile);
|
|
||||||
loadedProfile.ProfileBitmap = loadedProfile.ProfileIcon.ToBitmap(256, 256);
|
|
||||||
*/
|
|
||||||
if (ProfileRepository.IsActiveProfile(loadedProfile))
|
if (ProfileRepository.IsActiveProfile(loadedProfile))
|
||||||
_currentProfile = loadedProfile;
|
_currentProfile = loadedProfile;
|
||||||
|
|
||||||
@ -567,12 +566,20 @@ namespace DisplayMagicianShared
|
|||||||
_allProfiles.Sort();
|
_allProfiles.Sort();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/LoadProfiles: The {_profileStorageJsonFileName} profile JSON file exists but is empty! So we're going to treat it as if it didn't exist.");
|
||||||
|
UpdateActiveProfile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If we get here, then we don't have any profiles saved!
|
// If we get here, then we don't have any profiles saved!
|
||||||
// So we gotta start from scratch
|
// So we gotta start from scratch
|
||||||
// Create a new profile based on our current display settings
|
SharedLogger.logger.Debug($"ProfileRepository/LoadProfiles: Couldn't find the {_profileStorageJsonFileName} profile JSON file that contains the Profiles");
|
||||||
|
UpdateActiveProfile();
|
||||||
|
|
||||||
|
/* // Create a new profile based on our current display settings
|
||||||
ProfileItem myCurrentProfile = new ProfileItem
|
ProfileItem myCurrentProfile = new ProfileItem
|
||||||
{
|
{
|
||||||
Name = "Current Display Profile",
|
Name = "Current Display Profile",
|
||||||
@ -583,7 +590,7 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
// Save a profile Icon to the profile
|
// Save a profile Icon to the profile
|
||||||
_currentProfile.ProfileIcon = new ProfileIcon(_currentProfile);
|
_currentProfile.ProfileIcon = new ProfileIcon(_currentProfile);
|
||||||
_currentProfile.ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(256, 256);
|
_currentProfile.ProfileBitmap = _currentProfile.ProfileIcon.ToBitmap(256, 256);*/
|
||||||
}
|
}
|
||||||
_profilesLoaded = true;
|
_profilesLoaded = true;
|
||||||
return true;
|
return true;
|
||||||
@ -591,6 +598,7 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
public static bool SaveProfiles()
|
public static bool SaveProfiles()
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/SaveProfiles: Attempting to save the profiles repository to the {AppProfileStoragePath}.");
|
||||||
|
|
||||||
if (!Directory.Exists(AppProfileStoragePath))
|
if (!Directory.Exists(AppProfileStoragePath))
|
||||||
{
|
{
|
||||||
@ -615,9 +623,14 @@ namespace DisplayMagicianShared
|
|||||||
SharedLogger.logger.Fatal(ex, $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there.");
|
SharedLogger.logger.Fatal(ex, $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/SaveProfiles: Profiles folder {AppProfileStoragePath} exists.");
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/SaveProfiles: Converting the objects to JSON format.");
|
||||||
|
|
||||||
var json = JsonConvert.SerializeObject(_allProfiles, Formatting.Indented, new JsonSerializerSettings
|
var json = JsonConvert.SerializeObject(_allProfiles, Formatting.Indented, new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
NullValueHandling = NullValueHandling.Include,
|
NullValueHandling = NullValueHandling.Include,
|
||||||
@ -629,14 +642,15 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(json))
|
if (!string.IsNullOrWhiteSpace(json))
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/SaveProfiles: Saving the profile repository to the {_profileStorageJsonFileName}.");
|
||||||
|
|
||||||
File.WriteAllText(_profileStorageJsonFileName, json, Encoding.Unicode);
|
File.WriteAllText(_profileStorageJsonFileName, json, Encoding.Unicode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ProfileRepository/SaveProfiles exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
SharedLogger.logger.Error(ex, $"ProfileRepository/SaveProfiles: Unable to save the profile repository to the {_profileStorageJsonFileName}.");
|
||||||
Console.WriteLine($"Unable to save Profile JSON file {_profileStorageJsonFileName}: " + ex.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -644,10 +658,11 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
private static void SaveProfileIconToCache(ProfileItem profile)
|
private static void SaveProfileIconToCache(ProfileItem profile)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Work out the name of the Profile we'll save.
|
// Work out the name of the Profile we'll save.
|
||||||
profile.SavedProfileIconCacheFilename = System.IO.Path.Combine(AppProfileStoragePath, string.Concat(@"profile-", profile.UUID, @".ico"));
|
profile.SavedProfileIconCacheFilename = System.IO.Path.Combine(AppProfileStoragePath, string.Concat(@"profile-", profile.UUID, @".ico"));
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/SaveProfileIconToCache: Attempting to save the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder");
|
||||||
|
|
||||||
MultiIcon ProfileIcon;
|
MultiIcon ProfileIcon;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -656,11 +671,10 @@ namespace DisplayMagicianShared
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ProfileRepository/SaveProfileIconToCache exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
SharedLogger.logger.Warn(ex,$"ProfileRepository/SaveProfileIconToCache: Exception saving the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder. Using the default DisplayMagician icon instead");
|
||||||
// If we fail to create an icon based on the Profile, then we use the standard DisplayMagician profile one.
|
// If we fail to create an icon based on the Profile, then we use the standard DisplayMagician profile one.
|
||||||
// Which is created on program startup.
|
// Which is created on program startup.
|
||||||
File.Copy(AppDisplayMagicianIconFilename, profile.SavedProfileIconCacheFilename);
|
File.Copy(AppDisplayMagicianIconFilename, profile.SavedProfileIconCacheFilename);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,6 +682,8 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
public static List<string> GenerateProfileDisplayIdentifiers()
|
public static List<string> GenerateProfileDisplayIdentifiers()
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: Generating the unique Display Identifiers for the currently active profile");
|
||||||
|
|
||||||
List<string> displayIdentifiers = new List<string>();
|
List<string> displayIdentifiers = new List<string>();
|
||||||
|
|
||||||
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
|
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
|
||||||
@ -677,15 +693,16 @@ namespace DisplayMagicianShared
|
|||||||
{
|
{
|
||||||
myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs();
|
myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs();
|
||||||
isNvidia = true;
|
isNvidia = true;
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: The video card is a NVIDIA video card.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateProfileDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception.");
|
SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateProfileDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception. This means the video card isn't compatible with the NvAPIWrapper library we use. It is unlikely to be an NVIDIA video card.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0)
|
if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Debug("ProfileRepository/GenerateProfileDisplayIdentifiers: Was able to GetPhysicalCPUs through NvAPIWrapper library.");
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected");
|
||||||
|
|
||||||
foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs)
|
foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs)
|
||||||
{
|
{
|
||||||
@ -693,6 +710,7 @@ namespace DisplayMagicianShared
|
|||||||
NvAPIWrapper.GPU.GPUOutput[] myGPUOutputs = myPhysicalGPU.ActiveOutputs;
|
NvAPIWrapper.GPU.GPUOutput[] myGPUOutputs = myPhysicalGPU.ActiveOutputs;
|
||||||
foreach (NvAPIWrapper.GPU.GPUOutput aGPUOutput in myGPUOutputs)
|
foreach (NvAPIWrapper.GPU.GPUOutput aGPUOutput in myGPUOutputs)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to detect {myGPUOutputs.Length} outputs");
|
||||||
// Figure out the displaydevice attached to the output
|
// Figure out the displaydevice attached to the output
|
||||||
NvAPIWrapper.Display.DisplayDevice aConnectedDisplayDevice = myPhysicalGPU.GetDisplayDeviceByOutput(aGPUOutput);
|
NvAPIWrapper.Display.DisplayDevice aConnectedDisplayDevice = myPhysicalGPU.GetDisplayDeviceByOutput(aGPUOutput);
|
||||||
|
|
||||||
@ -716,6 +734,8 @@ namespace DisplayMagicianShared
|
|||||||
string displayIdentifier = String.Join("|", displayInfo);
|
string displayIdentifier = String.Join("|", displayInfo);
|
||||||
// Add it to the list of display identifiers so we can return it
|
// Add it to the list of display identifiers so we can return it
|
||||||
displayIdentifiers.Add(displayIdentifier);
|
displayIdentifiers.Add(displayIdentifier);
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -726,10 +746,11 @@ namespace DisplayMagicianShared
|
|||||||
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Then go through the adapters we have running using the WindowsDisplayAPI
|
// Then go through the adapters we have running using the WindowsDisplayAPI
|
||||||
List<Display> attachedDisplayDevices = Display.GetDisplays().ToList();
|
List<Display> attachedDisplayDevices = Display.GetDisplays().ToList();
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: We are using the standard Windows Display API to figure out what display devices are attached and available. There are {attachedDisplayDevices.Count} display devices detected.");
|
||||||
|
|
||||||
foreach (Display attachedDisplay in attachedDisplayDevices)
|
foreach (Display attachedDisplay in attachedDisplayDevices)
|
||||||
{
|
{
|
||||||
DisplayAdapter displayAdapter = attachedDisplay.Adapter;
|
DisplayAdapter displayAdapter = attachedDisplay.Adapter;
|
||||||
@ -795,7 +816,7 @@ namespace DisplayMagicianShared
|
|||||||
string displayIdentifier = String.Join("|", displayInfo);
|
string displayIdentifier = String.Join("|", displayInfo);
|
||||||
// Add it to the list of display identifiers so we can return it
|
// Add it to the list of display identifiers so we can return it
|
||||||
displayIdentifiers.Add(displayIdentifier);
|
displayIdentifiers.Add(displayIdentifier);
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -805,6 +826,8 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
public static List<string> GenerateAllAvailableDisplayIdentifiers()
|
public static List<string> GenerateAllAvailableDisplayIdentifiers()
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Generating all the Display Identifiers currently active now");
|
||||||
|
|
||||||
List<string> displayIdentifiers = new List<string>();
|
List<string> displayIdentifiers = new List<string>();
|
||||||
|
|
||||||
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
|
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
|
||||||
@ -814,19 +837,23 @@ namespace DisplayMagicianShared
|
|||||||
{
|
{
|
||||||
myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs();
|
myPhysicalGPUs = NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs();
|
||||||
isNvidia = true;
|
isNvidia = true;
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: The video card is a NVIDIA video card.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception.");
|
SharedLogger.logger.Debug(ex, "ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attemped to get GetPhysicalCPUs through NvAPIWrapper library but got exception. This means the video card isn't compatible with the NvAPIWrapper library we use. It is unlikely to be an NVIDIA video card.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0)
|
if (isNvidia && myPhysicalGPUs != null && myPhysicalGPUs.Length > 0)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected");
|
||||||
|
|
||||||
foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs)
|
foreach (NvAPIWrapper.GPU.PhysicalGPU myPhysicalGPU in myPhysicalGPUs)
|
||||||
{
|
{
|
||||||
// get a list of all physical outputs attached to the GPUs
|
// get a list of all physical outputs attached to the GPUs
|
||||||
NvAPIWrapper.Display.DisplayDevice[] allDisplayDevices = myPhysicalGPU.GetConnectedDisplayDevices(ConnectedIdsFlag.None);
|
NvAPIWrapper.Display.DisplayDevice[] allDisplayDevices = myPhysicalGPU.GetConnectedDisplayDevices(ConnectedIdsFlag.None);
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to detect {allDisplayDevices.Length} connected devices");
|
||||||
foreach (NvAPIWrapper.Display.DisplayDevice aDisplayDevice in allDisplayDevices)
|
foreach (NvAPIWrapper.Display.DisplayDevice aDisplayDevice in allDisplayDevices)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -852,6 +879,7 @@ namespace DisplayMagicianShared
|
|||||||
string displayIdentifier = String.Join("|", displayInfo);
|
string displayIdentifier = String.Join("|", displayInfo);
|
||||||
// Add it to the list of display identifiers so we can return it
|
// Add it to the list of display identifiers so we can return it
|
||||||
displayIdentifiers.Add(displayIdentifier);
|
displayIdentifiers.Add(displayIdentifier);
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,11 +890,14 @@ namespace DisplayMagicianShared
|
|||||||
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
// so that we can match valid AMD Eyefinity profiles with valid AMD standard profiles.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Then go through the adapters we have running using the WindowsDisplayAPI
|
// Then go through the adapters we have running using the WindowsDisplayAPI
|
||||||
List<Display> attachedDisplayDevices = Display.GetDisplays().ToList();
|
List<Display> attachedDisplayDevices = Display.GetDisplays().ToList();
|
||||||
List<UnAttachedDisplay> unattachedDisplayDevices = UnAttachedDisplay.GetUnAttachedDisplays().ToList();
|
List<UnAttachedDisplay> unattachedDisplayDevices = UnAttachedDisplay.GetUnAttachedDisplays().ToList();
|
||||||
|
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We are using the standard Windows Display API to figure out what display devices are attached and available. There are {attachedDisplayDevices.Count} display devices attached and {unattachedDisplayDevices.Count} devices unattached.");
|
||||||
|
|
||||||
|
|
||||||
foreach (Display attachedDisplay in attachedDisplayDevices)
|
foreach (Display attachedDisplay in attachedDisplayDevices)
|
||||||
{
|
{
|
||||||
DisplayAdapter displayAdapter = attachedDisplay.Adapter;
|
DisplayAdapter displayAdapter = attachedDisplay.Adapter;
|
||||||
@ -932,7 +963,7 @@ namespace DisplayMagicianShared
|
|||||||
string displayIdentifier = String.Join("|", displayInfo);
|
string displayIdentifier = String.Join("|", displayInfo);
|
||||||
// Add it to the list of display identifiers so we can return it
|
// Add it to the list of display identifiers so we can return it
|
||||||
displayIdentifiers.Add(displayIdentifier);
|
displayIdentifiers.Add(displayIdentifier);
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attached DisplayIdentifier: {displayIdentifier}");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (UnAttachedDisplay unattachedDisplay in unattachedDisplayDevices)
|
foreach (UnAttachedDisplay unattachedDisplay in unattachedDisplayDevices)
|
||||||
@ -990,7 +1021,7 @@ namespace DisplayMagicianShared
|
|||||||
string displayIdentifier = String.Join("|", displayInfo);
|
string displayIdentifier = String.Join("|", displayInfo);
|
||||||
// Add it to the list of display identifiers so we can return it
|
// Add it to the list of display identifiers so we can return it
|
||||||
displayIdentifiers.Add(displayIdentifier);
|
displayIdentifiers.Add(displayIdentifier);
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Unattached DisplayIdentifier: {displayIdentifier}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1000,7 +1031,7 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
public static bool ApplyNVIDIAGridTopology(ProfileItem profile)
|
public static bool ApplyNVIDIAGridTopology(ProfileItem profile)
|
||||||
{
|
{
|
||||||
Debug.Print("ProfileRepository.ApplyTopology()");
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyNVIDIAGridTopology: Attempting to apply NVIDIA Grid Topology");
|
||||||
|
|
||||||
if (!(profile is ProfileItem))
|
if (!(profile is ProfileItem))
|
||||||
return false;
|
return false;
|
||||||
@ -1019,6 +1050,7 @@ namespace DisplayMagicianShared
|
|||||||
// The profile we're changing to does not use NVIDIA Surround
|
// The profile we're changing to does not use NVIDIA Surround
|
||||||
// So we need to set the Grid Topologies to individual screens
|
// So we need to set the Grid Topologies to individual screens
|
||||||
// in preparation for the PathInfo step later
|
// in preparation for the PathInfo step later
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyNVIDIAGridTopology: Changing NVIDIA Grid Topology to individual screens so that we can move them to their final positions in a subsequent step");
|
||||||
var currentTopologies = GridTopology.GetGridTopologies();
|
var currentTopologies = GridTopology.GetGridTopologies();
|
||||||
|
|
||||||
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
||||||
@ -1033,22 +1065,23 @@ namespace DisplayMagicianShared
|
|||||||
}
|
}
|
||||||
} else if (surroundTopologies.Length > 0)
|
} else if (surroundTopologies.Length > 0)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyNVIDIAGridTopology: Changing NVIDIA Grid Topology to a surround screen so that we can move it to its final positions in a subsequent step");
|
||||||
// This profile is an NVIDIA Surround profile
|
// This profile is an NVIDIA Surround profile
|
||||||
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
||||||
}
|
}
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyNVIDIAGridTopology: NVIDIA Grid Topology successfully changed");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ProfileRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
SharedLogger.logger.Error(ex, $"ProfileRepository/ApplyNVIDIAGridTopology: Exception attempting to apply a change to the NVIDIA Grid Topology.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ApplyWindowsDisplayPathInfo(ProfileItem profile)
|
public static bool ApplyWindowsDisplayPathInfo(ProfileItem profile)
|
||||||
{
|
{
|
||||||
Debug.Print("ProfileRepository.ApplyPathInfo()");
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyWindowsDisplayPathInfo: Moving display screens to where they are supposed to be with this display profile");
|
||||||
if (!(profile is ProfileItem))
|
if (!(profile is ProfileItem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1056,11 +1089,12 @@ namespace DisplayMagicianShared
|
|||||||
{
|
{
|
||||||
var pathInfos = profile.Paths.Select(paths => paths.ToPathInfo()).Where(info => info != null).ToArray();
|
var pathInfos = profile.Paths.Select(paths => paths.ToPathInfo()).Where(info => info != null).ToArray();
|
||||||
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/ApplyWindowsDisplayPathInfo: Successfully moved display screens to where they are supposed to be");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ProfileRepository/ApplyPathInfo exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
SharedLogger.logger.Error(ex, $"ProfileRepository/ApplyWindowsDisplayPathInfo: Exception attempting to move the display screens to where they are supposed to be in this display profile.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1068,21 +1102,30 @@ namespace DisplayMagicianShared
|
|||||||
|
|
||||||
public static bool IsValidFilename(string testName)
|
public static bool IsValidFilename(string testName)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Trace($"ProfileRepository/IsValidFilename: Checking whether {testName} is a valid filename");
|
||||||
string strTheseAreInvalidFileNameChars = new string(System.IO.Path.GetInvalidFileNameChars());
|
string strTheseAreInvalidFileNameChars = new string(System.IO.Path.GetInvalidFileNameChars());
|
||||||
Regex regInvalidFileName = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
|
Regex regInvalidFileName = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
|
||||||
|
|
||||||
if (regInvalidFileName.IsMatch(testName)) { return false; };
|
if (regInvalidFileName.IsMatch(testName)) {
|
||||||
|
SharedLogger.logger.Trace($"ProfileRepository/IsValidFilename: {testName} is a valid filename");
|
||||||
return true;
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SharedLogger.logger.Debug($"ProfileRepository/IsValidFilename: {testName} isn't a valid filename as it contains one of these characters [" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetValidFilename(string uncheckedFilename)
|
public static string GetValidFilename(string uncheckedFilename)
|
||||||
{
|
{
|
||||||
|
SharedLogger.logger.Trace($"ProfileRepository/GetValidFilename: Modifying filename {uncheckedFilename} to be a valid filename for this filesystem");
|
||||||
string invalid = new string(System.IO.Path.GetInvalidFileNameChars()) + new string(System.IO.Path.GetInvalidPathChars());
|
string invalid = new string(System.IO.Path.GetInvalidFileNameChars()) + new string(System.IO.Path.GetInvalidPathChars());
|
||||||
foreach (char c in invalid)
|
foreach (char c in invalid)
|
||||||
{
|
{
|
||||||
uncheckedFilename = uncheckedFilename.Replace(c.ToString(), "");
|
uncheckedFilename = uncheckedFilename.Replace(c.ToString(), "");
|
||||||
}
|
}
|
||||||
|
SharedLogger.logger.Trace($"ProfileRepository/GetValidFilename: Modified filename {uncheckedFilename} so it is a valid filename for this filesystem");
|
||||||
return uncheckedFilename;
|
return uncheckedFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -40,7 +40,7 @@ DisplayMagician lets you set up the following information for each game or appli
|
|||||||
* Optionally rollback to your previous Display profile once the game or application has closed.
|
* Optionally rollback to your previous Display profile once the game or application has closed.
|
||||||
* Or maybe just create a Shortcut that permanently changes to a different Display Profile! The options are endless.
|
* Or maybe just create a Shortcut that permanently changes to a different Display Profile! The options are endless.
|
||||||
* Also comes with a Shell Extension that allows you to change to a different Display Profile by right-clicking on the desktop background!
|
* Also comes with a Shell Extension that allows you to change to a different Display Profile by right-clicking on the desktop background!
|
||||||
* Supports NVIDIA Surround and NVIDIA Mosaic settings
|
* Supports NVIDIA Surround setups (but doesn't support AMD Eyefinity yet... maybe someone wants to donate an AMD videocard?)
|
||||||
|
|
||||||
## Planned features
|
## Planned features
|
||||||
|
|
||||||
@ -52,10 +52,12 @@ DisplayMagician lets you set up the following information for each game or appli
|
|||||||
* Add Galaxy of Games Game Launcher (maybe?)
|
* Add Galaxy of Games Game Launcher (maybe?)
|
||||||
* Add Unit Tests!
|
* Add Unit Tests!
|
||||||
* Change UI from Winforms to better looking WPF
|
* Change UI from Winforms to better looking WPF
|
||||||
* Support of AMD Eyefinity (Needs a C# wrapper for AMD ADL)
|
* Support of AMD Eyefinity if someone donates an AMD video card to me (Needs a C# wrapper for AMD ADL)
|
||||||
|
|
||||||
## Donation
|
## Donation
|
||||||
I am doing this work to scratch a programming itch I've had for a while. It's pretty fun to take something carefully crafted by another developer and extend it with a lot of other awesome features. That said, I'd appreciate a donation to help buy a coffee or two! If you're so inclined, you can [sponsor me on GitHub Sponsors](https://github.com/sponsors/terrymacdonald).
|
I am doing this work to scratch a programming itch I've had for a while. It's pretty fun to take something carefully crafted by another developer and extend it with a lot of other awesome features. That said, I'd appreciate a donation to help buy a coffee or two!
|
||||||
|
|
||||||
|
<a href="https://www.buymeacoffee.com/displaymagician" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a><a href="https://github.com/sponsors/terrymacdonald" target="_blank"> <img src="https://github.com/terrymacdonald/DisplayMagician/raw/main/READMEAssets/gh-sponsor.png" alt="Github Sponsor" height="41" width="122"></a>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -119,4 +121,4 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
Thanks for the work and the time that all of our contributors put into making this a better project. Following is a short list, containing the name of some of these people:
|
Thanks for the work and the time that all of our contributors put into making this a better project. Following is a short list, containing the name of some of these people:
|
||||||
|
|
||||||
* Original HelioDisplayManagement project created by the amazing Soroush Falahati
|
* Original HelioDisplayManagement project created by the amazing Soroush Falahati
|
||||||
* Readme file created by @timegrinder
|
* Readme file created by @timegrinder
|
BIN
READMEAssets/gh-sponsor.png
Normal file
BIN
READMEAssets/gh-sponsor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
Loading…
Reference in New Issue
Block a user