2021-01-28 08:34:45 +00:00
using Newtonsoft.Json ;
2020-06-14 04:20:52 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing.IconLib ;
using System.IO ;
using System.Linq ;
using System.Text ;
using WindowsDisplayAPI.DisplayConfig ;
using NvAPIWrapper.Mosaic ;
using NvAPIWrapper.Native.Mosaic ;
using WindowsDisplayAPI ;
using System.Diagnostics ;
using System.Text.RegularExpressions ;
2020-10-10 02:18:30 +00:00
using NvAPIWrapper.Native.GPU ;
2021-05-21 02:41:49 +00:00
using System.Windows.Forms ;
2020-10-04 11:18:22 +00:00
2020-12-20 07:42:04 +00:00
namespace DisplayMagicianShared
2020-06-14 04:20:52 +00:00
{
2021-03-28 07:25:01 +00:00
2020-07-21 07:50:41 +00:00
public static class ProfileRepository
2020-06-14 04:20:52 +00:00
{
#region Class Variables
// Common items to the class
2020-08-07 03:59:23 +00:00
private static List < ProfileItem > _allProfiles = new List < ProfileItem > ( ) ;
2021-03-06 04:43:07 +00:00
public static Dictionary < string , bool > _profileWarningLookup = new Dictionary < string , bool > ( ) ;
2020-08-07 03:59:23 +00:00
private static bool _profilesLoaded = false ;
2020-11-22 07:49:37 +00:00
public static Version _version = new Version ( 1 , 0 , 0 ) ;
2020-10-09 03:27:59 +00:00
private static ProfileItem _currentProfile ;
2021-03-07 04:11:46 +00:00
private static List < string > _connectedDisplayIdentifiers = new List < string > ( ) ;
2021-05-21 02:41:49 +00:00
private static bool notifiedEDIDErrorToUser = false ;
2020-10-09 03:27:59 +00:00
2020-06-14 04:20:52 +00:00
// Other constants that are useful
2020-12-02 08:11:23 +00:00
public static string AppDataPath = System . IO . Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , "DisplayMagician" ) ;
2020-10-06 10:49:10 +00:00
public static string AppIconPath = System . IO . Path . Combine ( AppDataPath , $"Icons" ) ;
2020-12-02 08:11:23 +00:00
public static string AppDisplayMagicianIconFilename = System . IO . Path . Combine ( AppIconPath , @"DisplayMagician.ico" ) ;
2021-01-28 09:20:00 +00:00
private static readonly string AppProfileStoragePath = System . IO . Path . Combine ( AppDataPath , $"Profiles" ) ;
private static readonly string _profileStorageJsonFileName = System . IO . Path . Combine ( AppProfileStoragePath , $"DisplayProfiles_{_version.ToString(2)}.json" ) ;
2020-10-09 03:27:59 +00:00
2020-06-14 04:20:52 +00:00
#endregion
#region Class Constructors
2020-07-21 07:50:41 +00:00
static ProfileRepository ( )
2020-06-14 04:20:52 +00:00
{
2020-07-24 01:11:42 +00:00
// Initialise the the NVIDIA NvAPIWrapper
try
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ProfileRepository: Initialising the NvAPIWrapper.NVIDIA library." ) ;
2020-07-24 01:11:42 +00:00
NvAPIWrapper . NVIDIA . Initialize ( ) ;
2020-08-18 22:16:04 +00:00
// Create the Profile Storage Path if it doesn't exist so that it's avilable for all the program
if ( ! Directory . Exists ( AppProfileStoragePath ) )
{
2021-03-26 08:54:45 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ProfileRepository: Creating the Profiles storage folder {AppProfileStoragePath}." ) ;
2020-08-18 22:16:04 +00:00
Directory . CreateDirectory ( AppProfileStoragePath ) ;
}
2020-07-24 01:11:42 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician doesn't have permissions to create the Profiles storage folder {AppProfileStoragePath}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/ProfileRepository: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there." ) ;
}
2020-07-24 01:11:42 +00:00
catch ( Exception ex )
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/ProfileRepository: Initialising NVIDIA NvAPIWrapper caused an exception." ) ;
2020-07-24 01:11:42 +00:00
}
2020-06-14 04:20:52 +00:00
// Load the Profiles from storage
LoadProfiles ( ) ;
}
#endregion
#region Class Properties
public static List < ProfileItem > AllProfiles
{
get
{
2020-08-07 03:59:23 +00:00
if ( ! _profilesLoaded )
2020-06-14 04:20:52 +00:00
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
return _allProfiles ;
}
}
2021-03-06 04:43:07 +00:00
public static Dictionary < string , bool > ProfileWarningLookup
2021-03-05 01:44:53 +00:00
{
get
{
if ( ! _profilesLoaded )
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
2021-03-06 04:43:07 +00:00
return _profileWarningLookup ;
2021-03-05 01:44:53 +00:00
}
}
2020-06-14 04:20:52 +00:00
public static ProfileItem CurrentProfile
{
get
{
2020-10-09 03:27:59 +00:00
if ( _currentProfile = = null )
UpdateActiveProfile ( ) ;
2020-06-14 04:20:52 +00:00
return _currentProfile ;
}
set
{
if ( value is ProfileItem )
{
_currentProfile = value ;
// And if we have the _originalBitmap we can also save the Bitmap overlay, but only if the ProfileToUse is set
//if (_originalBitmap is Bitmap)
// _shortcutBitmap = ToBitmapOverlay(_originalBitmap, ProfileToUse.ProfileTightestBitmap, 256, 256);
}
}
}
public static int ProfileCount
{
get
{
2020-08-07 03:59:23 +00:00
if ( ! _profilesLoaded )
2020-06-15 09:57:46 +00:00
// Load the Profiles from storage if they need to be
LoadProfiles ( ) ;
2020-08-07 03:59:23 +00:00
2020-06-14 04:20:52 +00:00
return _allProfiles . Count ;
}
}
2021-03-07 04:11:46 +00:00
public static List < string > ConnectedDisplayIdentifiers
{
get
{
if ( _connectedDisplayIdentifiers . Count = = 0 )
// Load the Profiles from storage if they need to be
_connectedDisplayIdentifiers = GenerateAllAvailableDisplayIdentifiers ( ) ;
return _connectedDisplayIdentifiers ;
}
set
{
_connectedDisplayIdentifiers = value ;
}
}
2020-06-14 04:20:52 +00:00
#endregion
2021-03-07 04:11:46 +00:00
2020-06-14 04:20:52 +00:00
#region Class Methods
2020-08-19 06:55:50 +00:00
public static bool AddProfile ( ProfileItem profile )
2020-06-14 04:20:52 +00:00
{
2020-08-19 06:55:50 +00:00
if ( ! ( profile is ProfileItem ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/AddProfile: Adding profile {profile.Name} to our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Doublecheck if it already exists
// Because then we just update the one that already exists
2020-08-19 06:55:50 +00:00
if ( ! ContainsProfile ( profile ) )
2020-06-14 04:20:52 +00:00
{
// Add the Profile to the list of Profiles
2020-08-19 06:55:50 +00:00
_allProfiles . Add ( profile ) ;
2020-06-15 09:57:46 +00:00
2020-06-14 04:20:52 +00:00
// Generate the Profile Icon ready to be used
2020-08-19 06:55:50 +00:00
SaveProfileIconToCache ( profile ) ;
profile . PreSave ( ) ;
2020-06-14 04:20:52 +00:00
// Save the Profiles JSON as it's different
SaveProfiles ( ) ;
2020-08-19 06:55:50 +00:00
}
2020-06-14 04:20:52 +00:00
2021-03-05 01:44:53 +00:00
// Refresh the profiles to see whats valid
IsPossibleRefresh ( ) ;
2020-08-19 06:55:50 +00:00
//Doublecheck it's been added
if ( ContainsProfile ( profile ) )
{
2020-06-14 04:20:52 +00:00
return true ;
}
else
return false ;
}
2020-07-26 08:52:46 +00:00
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( ProfileItem profile )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( ! ( profile is ProfileItem ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile: Removing profile {profile.Name} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( profile . UUID ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( ArgumentException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
}
2020-06-14 04:20:52 +00:00
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( profile . UUID ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( string profileName )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( String . IsNullOrWhiteSpace ( profileName ) )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile2: Removing profile {profileName} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . Name . Equals ( profileName ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
}
catch ( ArgumentException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile2: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . Name . Equals ( profileName ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
2021-02-14 09:42:48 +00:00
public static bool RemoveProfile ( uint profileId )
2020-06-14 04:20:52 +00:00
{
2021-02-14 09:42:48 +00:00
if ( profileId = = 0 )
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RemoveProfile3: Removing profile wih profileId {profileId} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
// Remove the Profile Icons from the Cache
2021-02-14 09:42:48 +00:00
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( profileId ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician doesn't have permissions to delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/RemoveProfile3: DisplayMagician can't delete the cached Profile Icon {ProfileToRemove.SavedProfileIconCacheFilename} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
// Remove the Profile from the list.
2021-02-14 09:42:48 +00:00
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( profileId ) ) ;
2020-06-14 04:20:52 +00:00
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
2021-03-04 22:12:27 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
public static bool ContainsProfile ( ProfileItem Profile )
{
if ( ! ( Profile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Checking if our profile repository contains a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( Profile . UUID ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Our profile repository does contain a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile: Our profile repository doesn't contain a profile called {Profile.Name}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
public static bool ContainsProfile ( string ProfileNameOrId )
{
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Checking if our profile repository contains a profile with UUID or Name {ProfileNameOrId}" ) ;
2020-06-15 09:57:46 +00:00
if ( ProfileItem . IsValidUUID ( ProfileNameOrId ) )
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository does contain a profile with UUID {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository does contain a profile with Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsProfile2: Our profile repository doesn't contain a profile with a UUID or Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
2020-10-09 03:27:59 +00:00
public static bool ContainsCurrentProfile ( )
{
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Checking if our profile repository contains the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
2021-03-27 03:15:17 +00:00
// TODO - change for Equals
if ( testProfile . Equals ( _currentProfile ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Our profile repository does contain the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-10-09 03:27:59 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ContainsCurrentProfile: Our profile repository doesn't contain the display profile currently in use" ) ;
2020-10-09 03:27:59 +00:00
return false ;
}
2020-06-14 04:20:52 +00:00
public static ProfileItem GetProfile ( string ProfileNameOrId )
{
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Finding and returning {ProfileNameOrId} if it exists in our profile repository" ) ;
2020-06-14 04:20:52 +00:00
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/GetProfile: Profile to get was empty or only whitespace" ) ;
2020-06-14 04:20:52 +00:00
return null ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
2020-06-15 09:57:46 +00:00
if ( ProfileItem . IsValidUUID ( ProfileNameOrId ) )
2020-06-14 04:20:52 +00:00
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Returning profile with UUID {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return testProfile ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Returning profile with Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return testProfile ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetProfile: Didn't match any profiles with UUD or Name {ProfileNameOrId}" ) ;
2020-06-14 04:20:52 +00:00
return null ;
}
public static bool RenameProfile ( ProfileItem profile , string renamedName )
{
if ( ! ( profile is ProfileItem ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/RenameProfile: Profile to rename was empty or only whitespace" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: Attempting to rename profile {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
if ( ! IsValidFilename ( renamedName ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Error ( $"ProfileRepository/RenameProfile: The name the user wanted to renamed to profile to is not a valid filename" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
profile . Name = GetValidFilename ( renamedName ) ;
2021-03-05 01:44:53 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
// If it's been added to the list of AllProfiles
// then we also need to reproduce the Icons
if ( ContainsProfile ( profile ) )
{
// Save the Profiles JSON as it's different now
SaveProfiles ( ) ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: The profile was successfully renamed from {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
else
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/RenameProfile: The profile was not renamed from {profile.Name} to {renamedName}" ) ;
2020-06-14 04:20:52 +00:00
return false ;
2021-02-14 09:42:48 +00:00
}
2021-03-04 22:12:27 +00:00
2020-06-14 04:20:52 +00:00
}
2021-03-26 08:54:45 +00:00
/ * public static void UpdateActiveProfile ( )
2020-06-14 04:20:52 +00:00
{
2020-06-15 09:57:46 +00:00
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now)." ) ;
2020-06-15 09:57:46 +00:00
ProfileItem activeProfile = new ProfileItem
2020-06-14 04:20:52 +00:00
{
Name = "Current Display Profile" ,
2020-12-20 07:42:04 +00:00
Paths = PathInfo . GetActivePaths ( ) . Select ( info = > new DisplayMagicianShared . Topology . Path ( info ) ) . ToArray ( )
2020-06-14 04:20:52 +00:00
} ;
2020-09-18 10:52:18 +00:00
activeProfile . ProfileIcon = new ProfileIcon ( activeProfile ) ;
activeProfile . ProfileBitmap = activeProfile . ProfileIcon . ToBitmap ( 256 , 256 ) ;
2020-08-19 06:55:50 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
2020-06-15 09:57:46 +00:00
{
2020-08-07 03:59:23 +00:00
foreach ( ProfileItem loadedProfile in ProfileRepository . AllProfiles )
2020-06-15 09:57:46 +00:00
{
2020-10-09 03:27:59 +00:00
if ( activeProfile . Paths . SequenceEqual ( loadedProfile . Paths ) )
2020-08-07 03:59:23 +00:00
{
_currentProfile = loadedProfile ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The profile {loadedProfile.Name} is currently active (in use now)." ) ;
2020-08-07 03:59:23 +00:00
return ;
}
2020-06-15 09:57:46 +00:00
}
}
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The current profile is a new profile that doesn't already exist in the Profile Repository." ) ;
2020-06-15 09:57:46 +00:00
_currentProfile = activeProfile ;
2021-03-05 01:44:53 +00:00
//IsPossibleRefresh();
2021-03-26 08:54:45 +00:00
} * /
public static void UpdateActiveProfile ( )
{
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: Updating the profile currently active (in use now)." ) ;
ProfileItem activeProfile = new ProfileItem
{
Name = "Current Display Profile" ,
2021-03-26 10:55:35 +00:00
Paths = PathInfo . GetActivePaths ( ) . Select ( info = > new DisplayMagicianShared . Topology . Path ( info ) ) . ToArray ( ) ,
2021-03-27 03:15:17 +00:00
//ProfileDisplayIdentifiers = ProfileRepository.GenerateProfileDisplayIdentifiers()
2021-03-26 08:54:45 +00:00
} ;
activeProfile . ProfileIcon = new ProfileIcon ( activeProfile ) ;
activeProfile . ProfileBitmap = activeProfile . ProfileIcon . ToBitmap ( 256 , 256 ) ;
2020-06-14 04:20:52 +00:00
2021-03-26 08:54:45 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
{
foreach ( ProfileItem loadedProfile in ProfileRepository . AllProfiles )
{
if ( activeProfile . Equals ( loadedProfile ) )
{
_currentProfile = loadedProfile ;
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The profile {loadedProfile.Name} is currently active (in use now)." ) ;
return ;
}
}
}
SharedLogger . logger . Debug ( $"ProfileRepository/UpdateActiveProfile: The current profile is a new profile that doesn't already exist in the Profile Repository." ) ;
_currentProfile = activeProfile ;
//IsPossibleRefresh();
}
2020-06-14 04:20:52 +00:00
public static ProfileItem GetActiveProfile ( )
{
if ( ! ( _currentProfile is ProfileItem ) )
return null ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GetActiveProfile: Retrieving the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return _currentProfile ;
}
public static bool IsActiveProfile ( ProfileItem profile )
{
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
if ( ! ( profile is ProfileItem ) )
return false ;
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: Checking whether the profile {profile.Name} is the currently active profile." ) ;
2021-03-26 08:54:45 +00:00
//if (profile.Paths.SequenceEqual(_currentProfile.Paths))
if ( profile . Equals ( _currentProfile ) )
2021-02-14 09:42:48 +00:00
{
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: The profile {profile.Name} is the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return true ;
2021-02-14 09:42:48 +00:00
}
2020-06-14 04:20:52 +00:00
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/IsActiveProfile: The profile {profile.Name} is not the currently active profile." ) ;
2020-06-14 04:20:52 +00:00
return false ;
}
2020-10-10 04:50:27 +00:00
2020-06-14 04:20:52 +00:00
private static bool LoadProfiles ( )
{
2021-02-14 09:42:48 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Loading profiles from {_profileStorageJsonFileName} into the Profile Repository" ) ;
2020-06-14 04:20:52 +00:00
if ( File . Exists ( _profileStorageJsonFileName ) )
{
2021-02-20 09:03:19 +00:00
string json = "" ;
try
{
json = File . ReadAllText ( _profileStorageJsonFileName , Encoding . Unicode ) ;
}
catch ( Exception ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/LoadProfiles: Tried to read the JSON file {_profileStorageJsonFileName} to memory but File.ReadAllTextthrew an exception." ) ;
}
2020-06-14 04:20:52 +00:00
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
2021-02-14 09:42:48 +00:00
try
2020-06-14 04:20:52 +00:00
{
_allProfiles = JsonConvert . DeserializeObject < List < ProfileItem > > ( json , new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling . Ignore ,
NullValueHandling = NullValueHandling . Ignore ,
DefaultValueHandling = DefaultValueHandling . Include ,
2020-06-15 09:57:46 +00:00
TypeNameHandling = TypeNameHandling . Auto ,
ObjectCreationHandling = ObjectCreationHandling . Replace
2020-06-14 04:20:52 +00:00
} ) ;
}
2021-02-14 09:42:48 +00:00
catch ( Exception ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/LoadProfiles: Tried to parse the JSON in the {_profileStorageJsonFileName} but the JsonConvert threw an exception." ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-15 07:33:46 +00:00
2020-06-14 04:20:52 +00:00
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile" ,
2020-12-20 07:42:04 +00:00
Paths = PathInfo . GetActivePaths ( ) . Select ( info = > new DisplayMagicianShared . Topology . Path ( info ) ) . ToArray ( )
2020-06-14 04:20:52 +00:00
} ;
_currentProfile = myCurrentProfile ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Finding the current profile in the Profile Repository" ) ;
2020-06-14 04:20:52 +00:00
// Lookup all the Profile Names in the Saved Profiles
2020-06-15 09:57:46 +00:00
foreach ( ProfileItem loadedProfile in _allProfiles )
2020-06-14 04:20:52 +00:00
{
if ( ProfileRepository . IsActiveProfile ( loadedProfile ) )
_currentProfile = loadedProfile ;
}
2020-10-26 01:30:00 +00:00
// Sort the profiles alphabetically
_allProfiles . Sort ( ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-15 07:33:46 +00:00
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 ( ) ;
}
2021-02-10 09:40:22 +00:00
}
else
2020-06-14 04:20:52 +00:00
{
// If we get here, then we don't have any profiles saved!
// So we gotta start from scratch
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/LoadProfiles: Couldn't find the {_profileStorageJsonFileName} profile JSON file that contains the Profiles" ) ;
UpdateActiveProfile ( ) ;
2020-06-14 04:20:52 +00:00
}
2020-08-07 03:59:23 +00:00
_profilesLoaded = true ;
2021-03-07 04:11:46 +00:00
IsPossibleRefresh ( ) ;
2020-06-14 04:20:52 +00:00
return true ;
}
public static bool SaveProfiles ( )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Attempting to save the profiles repository to the {AppProfileStoragePath}." ) ;
2020-06-14 04:20:52 +00:00
2020-08-18 22:16:04 +00:00
if ( ! Directory . Exists ( AppProfileStoragePath ) )
2020-06-14 04:20:52 +00:00
{
try
{
2020-08-18 22:16:04 +00:00
Directory . CreateDirectory ( AppProfileStoragePath ) ;
2020-06-14 04:20:52 +00:00
}
2021-02-10 09:40:22 +00:00
catch ( UnauthorizedAccessException ex )
2020-06-14 04:20:52 +00:00
{
2021-02-10 09:40:22 +00:00
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician doesn't have permissions to create the Profiles storage folder {AppProfileStoragePath}." ) ;
}
catch ( ArgumentException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} due to an invalid argument." ) ;
}
catch ( PathTooLongException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the path is too long." ) ;
}
catch ( DirectoryNotFoundException ex )
{
SharedLogger . logger . Fatal ( ex , $"ProfileRepository/SaveProfiles: DisplayMagician can't create the Profiles storage folder {AppProfileStoragePath} as the parent folder isn't there." ) ;
2020-06-14 04:20:52 +00:00
}
}
2021-02-15 07:33:46 +00:00
else
{
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Profiles folder {AppProfileStoragePath} exists." ) ;
}
2020-06-14 04:20:52 +00:00
try
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Converting the objects to JSON format." ) ;
2020-06-14 04:20:52 +00:00
var json = JsonConvert . SerializeObject ( _allProfiles , Formatting . Indented , new JsonSerializerSettings
{
NullValueHandling = NullValueHandling . Include ,
DefaultValueHandling = DefaultValueHandling . Populate ,
TypeNameHandling = TypeNameHandling . Auto
} ) ;
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfiles: Saving the profile repository to the {_profileStorageJsonFileName}." ) ;
2020-06-14 04:20:52 +00:00
File . WriteAllText ( _profileStorageJsonFileName , json , Encoding . Unicode ) ;
return true ;
}
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/SaveProfiles: Unable to save the profile repository to the {_profileStorageJsonFileName}." ) ;
2020-06-14 04:20:52 +00:00
}
return false ;
}
private static void SaveProfileIconToCache ( ProfileItem profile )
{
// Work out the name of the Profile we'll save.
2020-10-06 10:49:10 +00:00
profile . SavedProfileIconCacheFilename = System . IO . Path . Combine ( AppProfileStoragePath , string . Concat ( @"profile-" , profile . UUID , @".ico" ) ) ;
2020-06-14 04:20:52 +00:00
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/SaveProfileIconToCache: Attempting to save the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder" ) ;
2020-06-14 04:20:52 +00:00
MultiIcon ProfileIcon ;
try
{
ProfileIcon = profile . ProfileIcon . ToIcon ( ) ;
ProfileIcon . Save ( profile . SavedProfileIconCacheFilename , MultiIconFormat . ICO ) ;
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/SaveProfileIconToCache: Exception saving the profile icon {profile.SavedProfileIconCacheFilename} to the {AppProfileStoragePath} folder. Using the default DisplayMagician icon instead" ) ;
2020-12-02 08:11:23 +00:00
// If we fail to create an icon based on the Profile, then we use the standard DisplayMagician profile one.
2020-06-14 04:20:52 +00:00
// Which is created on program startup.
2020-12-02 08:11:23 +00:00
File . Copy ( AppDisplayMagicianIconFilename , profile . SavedProfileIconCacheFilename ) ;
2020-06-14 04:20:52 +00:00
}
}
2021-03-04 21:34:51 +00:00
public static void IsPossibleRefresh ( )
2021-02-28 08:24:12 +00:00
{
// We need to refresh the cached answer
// Get the list of connected devices
2021-03-07 04:11:46 +00:00
ConnectedDisplayIdentifiers = GenerateAllAvailableDisplayIdentifiers ( ) ;
2021-02-28 08:24:12 +00:00
if ( _profilesLoaded & & _allProfiles . Count > 0 )
{
2021-03-05 01:44:53 +00:00
2021-02-28 08:24:12 +00:00
foreach ( ProfileItem loadedProfile in AllProfiles )
2021-03-07 04:11:46 +00:00
loadedProfile . RefreshPossbility ( ) ;
2021-02-28 08:24:12 +00:00
}
}
2020-10-06 10:49:10 +00:00
2020-10-06 07:59:59 +00:00
public static List < string > GenerateProfileDisplayIdentifiers ( )
2020-06-14 04:20:52 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: Generating the unique Display Identifiers for the currently active profile" ) ;
2020-10-06 07:59:59 +00:00
List < string > displayIdentifiers = new List < string > ( ) ;
2020-10-02 05:10:34 +00:00
2020-10-06 07:59:59 +00:00
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
2020-10-10 04:50:27 +00:00
bool isNvidia = false ;
NvAPIWrapper . GPU . PhysicalGPU [ ] myPhysicalGPUs = null ;
try
2020-10-06 07:59:59 +00:00
{
2020-10-10 04:50:27 +00:00
myPhysicalGPUs = NvAPIWrapper . GPU . PhysicalGPU . GetPhysicalGPUs ( ) ;
isNvidia = true ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: The video card is a NVIDIA video card." ) ;
2020-10-10 04:50:27 +00:00
}
catch ( Exception ex )
2021-02-07 01:42:17 +00:00
{
2021-02-15 07:33:46 +00:00
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." ) ;
2021-02-07 01:42:17 +00:00
}
2020-10-02 05:10:34 +00:00
2020-10-10 04:50:27 +00:00
if ( isNvidia & & myPhysicalGPUs ! = null & & myPhysicalGPUs . Length > 0 )
2021-04-09 08:21:02 +00:00
//if (false)
2020-10-10 04:50:27 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected" ) ;
2020-10-10 04:50:27 +00:00
foreach ( NvAPIWrapper . GPU . PhysicalGPU myPhysicalGPU in myPhysicalGPUs )
2020-10-06 07:59:59 +00:00
{
2020-10-10 04:50:27 +00:00
// get a list of all physical outputs attached to the GPUs
NvAPIWrapper . GPU . GPUOutput [ ] myGPUOutputs = myPhysicalGPU . ActiveOutputs ;
foreach ( NvAPIWrapper . GPU . GPUOutput aGPUOutput in myGPUOutputs )
2020-10-06 07:59:59 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: We were able to detect {myGPUOutputs.Length} outputs" ) ;
2020-10-10 04:50:27 +00:00
// Figure out the displaydevice attached to the output
NvAPIWrapper . Display . DisplayDevice aConnectedDisplayDevice = myPhysicalGPU . GetDisplayDeviceByOutput ( aGPUOutput ) ;
2020-10-06 07:59:59 +00:00
2020-10-10 04:50:27 +00:00
// Create an array of all the important display info we need to record
2021-04-21 10:14:30 +00:00
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 ( "#" ) ;
}
2020-10-06 07:59:59 +00:00
2020-10-10 04:50:27 +00:00
// Create a display identifier out of it
string displayIdentifier = String . Join ( "|" , displayInfo ) ;
// Add it to the list of display identifiers so we can return it
displayIdentifiers . Add ( displayIdentifier ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}" ) ;
2020-10-06 07:59:59 +00:00
}
2020-10-10 04:50:27 +00:00
2020-10-06 07:59:59 +00:00
}
}
// 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.
else
2020-06-14 04:20:52 +00:00
{
2020-10-06 07:59:59 +00:00
// Then go through the adapters we have running using the WindowsDisplayAPI
2020-10-10 04:50:27 +00:00
List < Display > attachedDisplayDevices = Display . GetDisplays ( ) . ToList ( ) ;
2021-02-15 07:33:46 +00:00
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." ) ;
2020-10-10 04:50:27 +00:00
foreach ( Display attachedDisplay in attachedDisplayDevices )
2020-10-02 05:10:34 +00:00
{
2021-05-21 02:41:49 +00:00
DisplayAdapter displayAdapter = null ;
PathDisplayAdapter pathDisplayAdapter = null ;
PathDisplaySource pathDisplaySource = null ;
PathDisplayTarget pathDisplayTarget = null ;
2020-10-10 04:50:27 +00:00
2021-05-21 02:41:49 +00:00
2021-04-21 10:14:30 +00:00
try
{
2021-05-21 02:41:49 +00:00
// We keep these lines here to detect if there is an exception so we can report it
// nicely to the user.
displayAdapter = attachedDisplay . Adapter ;
pathDisplayAdapter = displayAdapter . ToPathDisplayAdapter ( ) ;
pathDisplaySource = attachedDisplay . ToPathDisplaySource ( ) ;
pathDisplayTarget = attachedDisplay . ToPathDisplayTarget ( ) ;
// This line is just to force an EDID lookup first up so that we can deterine if there is an issue
// with the Monitor, and then tell the user
string EDIDManufacturerId = pathDisplayTarget . EDIDManufactureId . ToString ( ) ;
// print some trace messages so we can figure out issues if needed later
2021-04-21 10:14:30 +00:00
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}" ) ;
}
2021-05-21 02:41:49 +00:00
catch ( WindowsDisplayAPI . Exceptions . InvalidEDIDInformation ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!" ) ;
if ( ! notifiedEDIDErrorToUser )
{
MessageBox . Show (
$"Your monitor {attachedDisplay.DisplayFullName} is not responding when we ask about it's configuration. DisplayMagician may not be able to use this monitor!" , @"DisplayMagician cannot talk to your monitor" ,
MessageBoxButtons . OK ,
MessageBoxIcon . Error ) ;
notifiedEDIDErrorToUser = true ;
}
}
catch ( WindowsDisplayAPI . Exceptions . TargetNotAvailableException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception while we were trying to access the DisplayTarget to gather information about your display configuration." ) ;
}
2021-04-21 10:14:30 +00:00
catch ( Exception ex )
{
SharedLogger . logger . Warn ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception accessing one of the WindowsDisplayAPI items to print it out during a TRACE session" ) ;
}
2020-10-10 04:50:27 +00:00
// Create an array of all the important display info we need to record
2021-04-21 10:14:30 +00:00
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 ( ) ) ;
2021-05-21 02:41:49 +00:00
}
catch ( WindowsDisplayAPI . Exceptions . TargetNotAvailableException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers: Exception2 while we were trying to access the DisplayTarget to gather information about your display configuration." ) ;
2021-04-21 10:14:30 +00:00
}
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 ( ) ) ;
}
2021-05-21 02:41:49 +00:00
catch ( WindowsDisplayAPI . Exceptions . InvalidEDIDInformation ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!" ) ;
}
catch ( WindowsDisplayAPI . Exceptions . TargetNotAvailableException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception while we were trying to access the DisplayTarget to gather information about your display configuration." ) ;
}
2021-04-21 10:14:30 +00:00
catch ( Exception ex )
{
2021-05-21 02:41:49 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers2: Exception getting Windows Display EDID Manufacturer Code from video card. Substituting with a # instead" ) ;
2021-04-21 10:14:30 +00:00
displayInfo . Add ( "#" ) ;
}
try
{
displayInfo . Add ( pathDisplayTarget . EDIDManufactureId . ToString ( ) ) ;
}
2021-05-21 02:41:49 +00:00
catch ( WindowsDisplayAPI . Exceptions . InvalidEDIDInformation ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!" ) ;
}
catch ( WindowsDisplayAPI . Exceptions . TargetNotAvailableException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception while we were trying to access the DisplayTarget to gather information about your display configuration." ) ;
}
2021-04-21 10:14:30 +00:00
catch ( Exception ex )
{
2021-05-21 02:41:49 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers3: Exception getting Windows Display EDID Manufacturer ID from video card. Substituting with a # instead" ) ;
2021-04-21 10:14:30 +00:00
displayInfo . Add ( "#" ) ;
}
try
{
displayInfo . Add ( pathDisplayTarget . EDIDProductCode . ToString ( ) ) ;
}
2021-05-21 02:41:49 +00:00
catch ( WindowsDisplayAPI . Exceptions . InvalidEDIDInformation ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception while trying to get information from your monitor {attachedDisplay.DisplayFullName} about it's configuration. DisplayMagician may not be able to use this monitor!" ) ;
}
catch ( WindowsDisplayAPI . Exceptions . TargetNotAvailableException ex )
{
SharedLogger . logger . Error ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception while we were trying to access the DisplayTarget to gather information about your display configuration." ) ;
}
2021-04-21 10:14:30 +00:00
catch ( Exception ex )
{
2021-05-21 02:41:49 +00:00
SharedLogger . logger . Warn ( ex , $"ProfileRepository/GenerateProfileDisplayIdentifiers4: Exception getting Windows Display EDID Product Code from video card. Substituting with a # instead" ) ;
2021-04-21 10:14:30 +00:00
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 ( "#" ) ;
}
2020-10-06 08:32:31 +00:00
2020-10-10 04:50:27 +00:00
// Create a display identifier out of it
string displayIdentifier = String . Join ( "|" , displayInfo ) ;
// Add it to the list of display identifiers so we can return it
displayIdentifiers . Add ( displayIdentifier ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateProfileDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}" ) ;
2021-05-21 02:41:49 +00:00
2020-10-06 07:59:59 +00:00
}
}
2021-03-26 10:55:35 +00:00
// Sort the display identifiers
displayIdentifiers . Sort ( ) ;
2020-10-06 07:59:59 +00:00
return displayIdentifiers ;
}
2020-10-02 05:10:34 +00:00
2020-10-10 02:18:30 +00:00
public static List < string > GenerateAllAvailableDisplayIdentifiers ( )
2020-10-06 07:59:59 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Generating all the Display Identifiers currently active now" ) ;
2020-10-06 07:59:59 +00:00
List < string > displayIdentifiers = new List < string > ( ) ;
// If the Video Card is an NVidia, then we should generate specific NVidia displayIdentifiers
2020-10-10 02:18:30 +00:00
bool isNvidia = false ;
NvAPIWrapper . GPU . PhysicalGPU [ ] myPhysicalGPUs = null ;
try
2020-10-06 07:59:59 +00:00
{
2020-10-10 02:18:30 +00:00
myPhysicalGPUs = NvAPIWrapper . GPU . PhysicalGPU . GetPhysicalGPUs ( ) ;
isNvidia = true ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: The video card is a NVIDIA video card." ) ;
2020-10-10 02:18:30 +00:00
}
catch ( Exception ex )
2021-02-07 01:42:17 +00:00
{
2021-02-15 07:33:46 +00:00
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." ) ;
2021-02-07 01:42:17 +00:00
}
2020-10-06 07:59:59 +00:00
2020-10-10 02:18:30 +00:00
if ( isNvidia & & myPhysicalGPUs ! = null & & myPhysicalGPUs . Length > 0 )
2021-04-09 08:21:02 +00:00
//if (false)
2020-10-10 02:18:30 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to GetPhysicalCPUs through NvAPIWrapper library. There are {myPhysicalGPUs.Length} Physical GPUs detected" ) ;
2020-10-10 02:18:30 +00:00
foreach ( NvAPIWrapper . GPU . PhysicalGPU myPhysicalGPU in myPhysicalGPUs )
2020-10-02 05:10:34 +00:00
{
2020-10-10 02:18:30 +00:00
// get a list of all physical outputs attached to the GPUs
NvAPIWrapper . Display . DisplayDevice [ ] allDisplayDevices = myPhysicalGPU . GetConnectedDisplayDevices ( ConnectedIdsFlag . None ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: We were able to detect {allDisplayDevices.Length} connected devices" ) ;
2020-10-10 02:18:30 +00:00
foreach ( NvAPIWrapper . Display . DisplayDevice aDisplayDevice in allDisplayDevices )
2020-10-06 07:59:59 +00:00
{
2020-10-02 05:10:34 +00:00
2020-10-10 02:18:30 +00:00
if ( aDisplayDevice . IsAvailable = = true )
{
2020-10-06 07:59:59 +00:00
// Create an array of all the important display info we need to record
2021-04-21 10:14:30 +00:00
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 ( "#" ) ;
}
2020-10-06 07:59:59 +00:00
// Create a display identifier out of it
string displayIdentifier = String . Join ( "|" , displayInfo ) ;
// Add it to the list of display identifiers so we can return it
displayIdentifiers . Add ( displayIdentifier ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DisplayIdentifier: {displayIdentifier}" ) ;
2020-10-06 07:59:59 +00:00
}
}
}
2020-10-02 05:10:34 +00:00
}
2021-04-21 10:14:30 +00:00
// else videocard is not NVIDIA so we just use the WindowsAPI access method
2020-10-06 07:59:59 +00:00
// 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.
else
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
2020-10-06 07:59:59 +00:00
// Then go through the adapters we have running using the WindowsDisplayAPI
2020-10-10 04:50:27 +00:00
List < Display > attachedDisplayDevices = Display . GetDisplays ( ) . ToList ( ) ;
List < UnAttachedDisplay > unattachedDisplayDevices = UnAttachedDisplay . GetUnAttachedDisplays ( ) . ToList ( ) ;
2021-02-15 07:33:46 +00:00
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." ) ;
2020-10-10 04:50:27 +00:00
foreach ( Display attachedDisplay in attachedDisplayDevices )
2020-10-06 07:59:59 +00:00
{
2020-10-10 04:50:27 +00:00
DisplayAdapter displayAdapter = attachedDisplay . Adapter ;
2020-10-06 07:59:59 +00:00
PathDisplayAdapter pathDisplayAdapter = displayAdapter . ToPathDisplayAdapter ( ) ;
2020-10-10 04:50:27 +00:00
PathDisplaySource pathDisplaySource = attachedDisplay . ToPathDisplaySource ( ) ;
PathDisplayTarget pathDisplayTarget = attachedDisplay . ToPathDisplayTarget ( ) ;
2021-04-21 10:14:30 +00:00
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" ) ;
}
2020-10-10 04:50:27 +00:00
// Create an array of all the important display info we need to record
2021-04-21 10:14:30 +00:00
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 ( "#" ) ;
}
2020-10-06 08:32:31 +00:00
2020-10-10 04:50:27 +00:00
// Create a display identifier out of it
string displayIdentifier = String . Join ( "|" , displayInfo ) ;
// Add it to the list of display identifiers so we can return it
displayIdentifiers . Add ( displayIdentifier ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Attached DisplayIdentifier: {displayIdentifier}" ) ;
2020-10-10 04:50:27 +00:00
}
2020-10-06 07:59:59 +00:00
2020-10-10 04:50:27 +00:00
foreach ( UnAttachedDisplay unattachedDisplay in unattachedDisplayDevices )
{
DisplayAdapter displayAdapter = unattachedDisplay . Adapter ;
PathDisplayAdapter pathDisplayAdapter = displayAdapter . ToPathDisplayAdapter ( ) ;
PathDisplaySource pathDisplaySource = unattachedDisplay . ToPathDisplaySource ( ) ;
PathDisplayTarget pathDisplayTarget = unattachedDisplay . ToPathDisplayTarget ( ) ;
2021-04-09 08:21:02 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDN : {unattachedDisplay.DeviceName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDFN : {unattachedDisplay.DisplayFullName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.DisplayName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIN : {unattachedDisplay.IsAvailable}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: ADDIV : {unattachedDisplay.IsValid}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DP : {displayAdapter.DevicePath}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DN : {displayAdapter.DeviceName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: DK : {displayAdapter.DeviceKey}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AI : {pathDisplayAdapter.AdapterId}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIDP : {pathDisplayAdapter.DevicePath}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: AIII : {pathDisplayAdapter.IsInvalid}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSA : {pathDisplaySource.Adapter}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSCDS : {pathDisplaySource.CurrentDPIScale}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSDN : {pathDisplaySource.DisplayName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSMDS : {pathDisplaySource.MaximumDPIScale}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSRDS : {pathDisplaySource.RecommendedDPIScale}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDSSI : {pathDisplaySource.SourceId}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTA : {pathDisplayTarget.Adapter}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTCI : {pathDisplayTarget.ConnectorInstance}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTDP : {pathDisplayTarget.DevicePath}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMC : {pathDisplayTarget.EDIDManufactureCode}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEMI : {pathDisplayTarget.EDIDManufactureId}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTEPC : {pathDisplayTarget.EDIDProductCode}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTFN : {pathDisplayTarget.FriendlyName}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTIA : {pathDisplayTarget.IsAvailable}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPR : {pathDisplayTarget.PreferredResolution}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTPSM : {pathDisplayTarget.PreferredSignalMode}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTTI : {pathDisplayTarget.TargetId}" ) ;
SharedLogger . logger . Trace ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: PDTVRS : {pathDisplayTarget.VirtualResolutionSupport}" ) ;
2020-10-10 04:50:27 +00:00
// 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 ( ) ,
} ;
// Create a display identifier out of it
string displayIdentifier = String . Join ( "|" , displayInfo ) ;
// Add it to the list of display identifiers so we can return it
displayIdentifiers . Add ( displayIdentifier ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/GenerateAllAvailableDisplayIdentifiers: Unattached DisplayIdentifier: {displayIdentifier}" ) ;
2020-10-06 07:59:59 +00:00
}
2020-10-02 05:10:34 +00:00
}
2020-10-06 07:59:59 +00:00
2021-03-26 10:55:35 +00:00
// Sort the display identifiers
displayIdentifiers . Sort ( ) ;
2020-10-06 07:59:59 +00:00
return displayIdentifiers ;
2020-10-02 05:10:34 +00:00
}
2020-10-07 08:58:05 +00:00
public static bool ApplyNVIDIAGridTopology ( ProfileItem profile )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: Attempting to apply NVIDIA Grid Topology" ) ;
2020-10-04 10:01:03 +00:00
if ( ! ( profile is ProfileItem ) )
return false ;
2020-10-02 05:10:34 +00:00
try
{
var surroundTopologies =
2020-10-07 08:32:12 +00:00
profile . Paths . SelectMany ( paths = > paths . TargetDisplays )
2020-10-02 05:10:34 +00:00
. Select ( target = > target . SurroundTopology )
. Where ( topology = > topology ! = null )
. Select ( topology = > topology . ToGridTopology ( ) )
. ToArray ( ) ;
if ( surroundTopologies . Length = = 0 )
{
2020-10-07 08:58:05 +00:00
// The profile we're changing to does not use NVIDIA Surround
// So we need to set the Grid Topologies to individual screens
// in preparation for the PathInfo step later
2021-02-15 07:33:46 +00:00
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" ) ;
2020-10-02 05:10:34 +00:00
var currentTopologies = GridTopology . GetGridTopologies ( ) ;
if ( currentTopologies . Any ( topology = > topology . Rows * topology . Columns > 1 ) )
{
surroundTopologies =
GridTopology . GetGridTopologies ( )
. SelectMany ( topology = > topology . Displays )
. Select ( displays = > new GridTopology ( 1 , 1 , new [ ] { displays } ) )
. ToArray ( ) ;
2020-10-07 08:32:12 +00:00
GridTopology . SetGridTopologies ( surroundTopologies , SetDisplayTopologyFlag . MaximizePerformance ) ;
2020-10-02 05:10:34 +00:00
}
2020-10-04 10:01:03 +00:00
} else if ( surroundTopologies . Length > 0 )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
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" ) ;
2020-10-04 10:01:03 +00:00
// This profile is an NVIDIA Surround profile
2020-10-02 05:10:34 +00:00
GridTopology . SetGridTopologies ( surroundTopologies , SetDisplayTopologyFlag . MaximizePerformance ) ;
}
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyNVIDIAGridTopology: NVIDIA Grid Topology successfully changed" ) ;
2020-10-04 10:01:03 +00:00
return true ;
2020-10-02 05:10:34 +00:00
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/ApplyNVIDIAGridTopology: Exception attempting to apply a change to the NVIDIA Grid Topology." ) ;
2020-10-04 10:01:03 +00:00
return false ;
2020-10-02 05:10:34 +00:00
}
}
2020-10-07 08:58:05 +00:00
public static bool ApplyWindowsDisplayPathInfo ( ProfileItem profile )
2020-10-02 05:10:34 +00:00
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyWindowsDisplayPathInfo: Moving display screens to where they are supposed to be with this display profile" ) ;
2020-10-04 10:01:03 +00:00
if ( ! ( profile is ProfileItem ) )
return false ;
2020-10-02 05:10:34 +00:00
2020-10-04 10:01:03 +00:00
try
2020-10-02 05:10:34 +00:00
{
2020-10-07 08:32:12 +00:00
var pathInfos = profile . Paths . Select ( paths = > paths . ToPathInfo ( ) ) . Where ( info = > info ! = null ) . ToArray ( ) ;
2020-10-07 07:08:36 +00:00
PathInfo . ApplyPathInfos ( pathInfos , true , true , true ) ;
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Debug ( $"ProfileRepository/ApplyWindowsDisplayPathInfo: Successfully moved display screens to where they are supposed to be" ) ;
2020-10-04 10:01:03 +00:00
return true ;
}
catch ( Exception ex )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Error ( ex , $"ProfileRepository/ApplyWindowsDisplayPathInfo: Exception attempting to move the display screens to where they are supposed to be in this display profile." ) ;
2020-10-04 10:01:03 +00:00
return false ;
2020-10-02 05:10:34 +00:00
}
}
2020-07-23 06:31:00 +00:00
2020-06-14 04:20:52 +00:00
public static bool IsValidFilename ( string testName )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/IsValidFilename: Checking whether {testName} is a valid filename" ) ;
2020-10-06 10:49:10 +00:00
string strTheseAreInvalidFileNameChars = new string ( System . IO . Path . GetInvalidFileNameChars ( ) ) ;
2020-06-14 04:20:52 +00:00
Regex regInvalidFileName = new Regex ( "[" + Regex . Escape ( strTheseAreInvalidFileNameChars ) + "]" ) ;
2021-02-15 07:33:46 +00:00
if ( regInvalidFileName . IsMatch ( testName ) ) {
SharedLogger . logger . Trace ( $"ProfileRepository/IsValidFilename: {testName} is a valid filename" ) ;
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 ;
}
2020-06-14 04:20:52 +00:00
}
public static string GetValidFilename ( string uncheckedFilename )
{
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/GetValidFilename: Modifying filename {uncheckedFilename} to be a valid filename for this filesystem" ) ;
2020-10-06 10:49:10 +00:00
string invalid = new string ( System . IO . Path . GetInvalidFileNameChars ( ) ) + new string ( System . IO . Path . GetInvalidPathChars ( ) ) ;
2020-06-14 04:20:52 +00:00
foreach ( char c in invalid )
{
uncheckedFilename = uncheckedFilename . Replace ( c . ToString ( ) , "" ) ;
}
2021-02-15 07:33:46 +00:00
SharedLogger . logger . Trace ( $"ProfileRepository/GetValidFilename: Modified filename {uncheckedFilename} so it is a valid filename for this filesystem" ) ;
2020-06-14 04:20:52 +00:00
return uncheckedFilename ;
}
#endregion
}
[global::System.Serializable]
public class ProfileRepositoryException : Exception
{
public ProfileRepositoryException ( ) { }
public ProfileRepositoryException ( string message ) : base ( message ) { }
public ProfileRepositoryException ( string message , Exception inner ) : base ( message , inner ) { }
protected ProfileRepositoryException (
System . Runtime . Serialization . SerializationInfo info ,
System . Runtime . Serialization . StreamingContext context ) : base ( info , context ) { }
}
}
2020-10-06 07:59:59 +00:00