2020-06-14 04:20:52 +00:00
using HeliosPlus.Shared ;
using Newtonsoft.Json ;
using System ;
using System.Collections.Generic ;
using System.Drawing.IconLib ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Text ;
using WindowsDisplayAPI.DisplayConfig ;
using HeliosPlus.Shared.Resources ;
using Newtonsoft.Json ;
using NvAPIWrapper.Mosaic ;
using NvAPIWrapper.Native.Mosaic ;
using HeliosPlus.Shared.Topology ;
using System.Drawing ;
using System.Drawing.Imaging ;
using WindowsDisplayAPI ;
using System.Diagnostics ;
using System.Threading ;
2020-10-02 05:10:34 +00:00
using System.Threading ;
using System.Threading.Tasks ;
2020-06-14 04:20:52 +00:00
using System.Windows.Forms ;
using System.Text.RegularExpressions ;
using System.Resources ;
2020-07-23 06:31:00 +00:00
using System.Net.NetworkInformation ;
using NvAPIWrapper.Mosaic ;
using NvAPIWrapper.Native.Mosaic ;
2020-08-19 06:55:50 +00:00
using HeliosPlus.Shared.DisplayIdentification ;
2020-06-14 04:20:52 +00:00
namespace HeliosPlus.Shared
{
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 > ( ) ;
private static bool _profilesLoaded = false ;
2020-06-14 04:20:52 +00:00
public static Version Version = new Version ( 1 , 0 , 0 ) ;
// Other constants that are useful
public static string AppDataPath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , "HeliosPlus" ) ;
public static string AppIconPath = Path . Combine ( AppDataPath , $"Icons" ) ;
public static string AppHeliosPlusIconFilename = Path . Combine ( AppIconPath , @"HeliosPlus.ico" ) ;
2020-08-18 22:16:04 +00:00
private static string AppProfileStoragePath = Path . Combine ( AppDataPath , $"Profiles" ) ;
private static string _profileStorageJsonFileName = Path . Combine ( AppProfileStoragePath , $"DisplayProfiles_{Version.ToString(2)}.json" ) ;
2020-06-14 04:20:52 +00:00
private static uint _lastProfileId ;
private static ProfileItem _currentProfile ;
2020-09-30 09:49:02 +00:00
//private static List<Display> _availableDisplays;
//private static List<UnAttachedDisplay> _unavailableDisplays;
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
{
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 ) )
{
Directory . CreateDirectory ( AppProfileStoragePath ) ;
}
2020-07-24 01:11:42 +00:00
}
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ShortcutItem/Instansiation exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-07-24 01:11:42 +00:00
// ignored
}
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 ;
}
}
public static ProfileItem CurrentProfile
{
get
{
UpdateActiveProfile ( ) ;
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 ;
}
}
#endregion
2020-07-26 08:52: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 ;
// 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
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
2020-06-14 04:20:52 +00:00
public static bool RemoveProfile ( ProfileItem Profile )
{
if ( ! ( Profile is ProfileItem ) )
return false ;
// Remove the Profile Icons from the Cache
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( Profile . UUID ) ) ;
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2020-07-15 08:11:38 +00:00
catch ( Exception ex )
2020-06-14 04:20:52 +00:00
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/RemoveProfile exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// TODO check and report
}
}
// Remove the Profile from the list.
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( Profile . UUID ) ) ;
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
public static bool RemoveProfile ( string ProfileName )
{
if ( String . IsNullOrWhiteSpace ( ProfileName ) )
return false ;
// Remove the Profile Icons from the Cache
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . Name . Equals ( ProfileName ) ) ;
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2020-07-15 08:11:38 +00:00
catch ( Exception ex )
2020-06-14 04:20:52 +00:00
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/RemoveProfile exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// TODO check and report
}
}
// Remove the Profile from the list.
int numRemoved = _allProfiles . RemoveAll ( item = > item . Name . Equals ( ProfileName ) ) ;
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
public static bool RemoveProfile ( uint ProfileId )
{
if ( ProfileId = = 0 )
return false ;
// Remove the Profile Icons from the Cache
List < ProfileItem > ProfilesToRemove = _allProfiles . FindAll ( item = > item . UUID . Equals ( ProfileId ) ) ;
foreach ( ProfileItem ProfileToRemove in ProfilesToRemove )
{
try
{
File . Delete ( ProfileToRemove . SavedProfileIconCacheFilename ) ;
}
2020-07-15 08:11:38 +00:00
catch ( Exception ex )
2020-06-14 04:20:52 +00:00
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/RemoveProfile exception 3: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// TODO check and report
}
}
// Remove the Profile from the list.
int numRemoved = _allProfiles . RemoveAll ( item = > item . UUID . Equals ( ProfileId ) ) ;
if ( numRemoved = = 1 )
{
SaveProfiles ( ) ;
return true ;
}
else if ( numRemoved = = 0 )
return false ;
else
throw new ProfileRepositoryException ( ) ;
}
public static bool ContainsProfile ( ProfileItem Profile )
{
if ( ! ( Profile is ProfileItem ) )
return false ;
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . UUID . Equals ( Profile . UUID ) )
return true ;
}
return false ;
}
public static bool ContainsProfile ( string ProfileNameOrId )
{
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
return false ;
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 ) )
return true ;
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
return true ;
}
return false ;
}
public static ProfileItem GetProfile ( string ProfileNameOrId )
{
if ( String . IsNullOrWhiteSpace ( ProfileNameOrId ) )
return null ;
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 ) )
return testProfile ;
}
else
foreach ( ProfileItem testProfile in _allProfiles )
{
if ( testProfile . Name . Equals ( ProfileNameOrId ) )
return testProfile ;
}
return null ;
}
public static bool RenameProfile ( ProfileItem profile , string renamedName )
{
if ( ! ( profile is ProfileItem ) )
return false ;
if ( ! IsValidFilename ( renamedName ) )
return false ;
profile . Name = GetValidFilename ( renamedName ) ;
// If it's been added to the list of AllProfiles
// then we also need to reproduce the Icons
if ( ContainsProfile ( profile ) )
{
// rename the old Profile Icon to the new name
2020-06-15 09:57:46 +00:00
//string newSavedProfileIconCacheFilename = Path.Combine(_profileStorageJsonPath, String.Concat(@"profile-", profile.UUID, @".ico"));
//File.Move(profile.SavedProfileIconCacheFilename, newSavedProfileIconCacheFilename);
2020-06-14 04:20:52 +00:00
// Then update the profile too
2020-06-15 09:57:46 +00:00
//profile.SavedProfileIconCacheFilename = newSavedProfileIconCacheFilename;
2020-06-14 04:20:52 +00:00
// Save the Profiles JSON as it's different now
SaveProfiles ( ) ;
return true ;
}
else
return false ;
}
public static void UpdateActiveProfile ( )
{
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-09-18 10:52:18 +00:00
Viewports = PathInfo . GetActivePaths ( ) . Select ( info = > new ProfileViewport ( 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-08-07 03:59:23 +00:00
if ( activeProfile . Equals ( loadedProfile ) )
{
_currentProfile = loadedProfile ;
return ;
}
2020-06-15 09:57:46 +00:00
}
}
_currentProfile = activeProfile ;
2020-06-14 04:20:52 +00:00
}
public static ProfileItem GetActiveProfile ( )
{
UpdateActiveProfile ( ) ;
if ( ! ( _currentProfile is ProfileItem ) )
return null ;
return _currentProfile ;
}
public static bool IsActiveProfile ( ProfileItem profile )
{
UpdateActiveProfile ( ) ;
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
if ( ! ( profile is ProfileItem ) )
return false ;
if ( profile . Equals ( _currentProfile ) )
return true ;
return false ;
}
2020-09-30 09:49:02 +00:00
public static bool IsPossibleProfile ( ProfileItem profile )
{
if ( ! ( _currentProfile is ProfileItem ) )
return false ;
if ( ! ( profile is ProfileItem ) )
return false ;
// Check each display in this profile and make sure it's currently available
2020-10-02 05:10:34 +00:00
int validDisplayCount = 0 ;
2020-09-30 09:49:02 +00:00
foreach ( string profileDisplayIdentifier in profile . ProfileDisplayIdentifiers )
{
// If this profile has a display that isn't currently available then we need to say it's a no!
2020-10-02 05:10:34 +00:00
if ( _currentProfile . ProfileDisplayIdentifiers . Contains ( profileDisplayIdentifier ) )
validDisplayCount + + ;
2020-09-30 09:49:02 +00:00
}
2020-10-02 05:10:34 +00:00
if ( validDisplayCount = = profile . ProfileDisplayIdentifiers . Count )
return true ;
else
return false ;
2020-09-30 09:49:02 +00:00
}
2020-06-14 04:20:52 +00:00
private static bool LoadProfiles ( )
{
if ( File . Exists ( _profileStorageJsonFileName ) )
{
var json = File . ReadAllText ( _profileStorageJsonFileName , Encoding . Unicode ) ;
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
2020-06-15 09:57:46 +00:00
//List<ProfileItem> profiles = new List<ProfileItem>();
2020-06-14 04:20:52 +00:00
try
{
_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
} ) ;
}
catch ( Exception ex )
{
// ignored
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/LoadProfiles exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
Console . WriteLine ( $"Unable to load Profiles from JSON file {_profileStorageJsonFileName}: " + ex . Message ) ;
}
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile" ,
Viewports = PathInfo . GetActivePaths ( ) . Select ( info = > new ProfileViewport ( info ) ) . ToArray ( )
} ;
_currentProfile = myCurrentProfile ;
// 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
{
// Save a profile Icon to the profile
2020-06-15 09:57:46 +00:00
/ * loadedProfile . ProfileIcon = new ProfileIcon ( loadedProfile ) ;
loadedProfile . ProfileBitmap = loadedProfile . ProfileIcon . ToBitmap ( 256 , 256 ) ;
* /
2020-06-14 04:20:52 +00:00
if ( ProfileRepository . IsActiveProfile ( loadedProfile ) )
_currentProfile = loadedProfile ;
}
}
} else
{
// If we get here, then we don't have any profiles saved!
// So we gotta start from scratch
// Create a new profile based on our current display settings
ProfileItem myCurrentProfile = new ProfileItem
{
Name = "Current Display Profile" ,
Viewports = PathInfo . GetActivePaths ( ) . Select ( info = > new ProfileViewport ( info ) ) . ToArray ( )
} ;
_currentProfile = myCurrentProfile ;
// Save a profile Icon to the profile
_currentProfile . ProfileIcon = new ProfileIcon ( _currentProfile ) ;
_currentProfile . ProfileBitmap = _currentProfile . ProfileIcon . ToBitmap ( 256 , 256 ) ;
}
2020-08-07 03:59:23 +00:00
_profilesLoaded = true ;
2020-06-14 04:20:52 +00:00
return true ;
}
public static bool SaveProfiles ( )
{
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
}
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/SaveProfiles exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-08-18 22:16:04 +00:00
Console . WriteLine ( $"Unable to create Profile folder {AppProfileStoragePath}: " + ex . Message ) ;
2020-06-14 04:20:52 +00:00
}
}
try
{
var json = JsonConvert . SerializeObject ( _allProfiles , Formatting . Indented , new JsonSerializerSettings
{
NullValueHandling = NullValueHandling . Include ,
DefaultValueHandling = DefaultValueHandling . Populate ,
TypeNameHandling = TypeNameHandling . Auto
} ) ;
if ( ! string . IsNullOrWhiteSpace ( json ) )
{
File . WriteAllText ( _profileStorageJsonFileName , json , Encoding . Unicode ) ;
return true ;
}
}
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/SaveProfiles exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
Console . WriteLine ( $"Unable to save Profile JSON file {_profileStorageJsonFileName}: " + ex . Message ) ;
}
return false ;
}
private static void SaveProfileIconToCache ( ProfileItem profile )
{
// Work out the name of the Profile we'll save.
2020-08-18 22:16:04 +00:00
profile . SavedProfileIconCacheFilename = Path . Combine ( AppProfileStoragePath , String . Concat ( @"profile-" , profile . UUID , @".ico" ) ) ;
2020-06-14 04:20:52 +00:00
MultiIcon ProfileIcon ;
try
{
ProfileIcon = profile . ProfileIcon . ToIcon ( ) ;
ProfileIcon . Save ( profile . SavedProfileIconCacheFilename , MultiIconFormat . ICO ) ;
}
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"ProfileRepository/SaveProfileIconToCache exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// If we fail to create an icon based on the Profile, then we use the standard HeliosPlus profile one.
// Which is created on program startup.
File . Copy ( AppHeliosPlusIconFilename , profile . SavedProfileIconCacheFilename ) ;
}
}
2020-10-02 05:10:34 +00:00
public static bool ApplyProfile ( ProfileItem profile )
2020-06-14 04:20:52 +00:00
{
2020-10-02 05:10:34 +00:00
// If we're already on the wanted profile then no need to change!
if ( ProfileRepository . IsActiveProfile ( profile ) )
return true ;
// We need to check if the profile is valid
if ( ! profile . IsPossible )
return false ;
try
2020-06-14 04:20:52 +00:00
{
2020-10-02 05:10:34 +00:00
// Now lets start by changing the display topology
Task applyProfileTopologyTask = Task . Run ( ( ) = >
{
Console . WriteLine ( "ShortcutRepository/SaveShortcutIconToCache : Applying Profile Topology" + profile . Name ) ;
ApplyTopology ( profile ) ;
} ) ;
applyProfileTopologyTask . Wait ( ) ;
// And then change the path information
Task applyProfilePathInfoTask = Task . Run ( ( ) = >
{
Console . WriteLine ( "ShortcutRepository/SaveShortcutIconToCache : Applying Profile Topology" + profile . Name ) ;
ApplyPathInfo ( profile ) ;
} ) ;
applyProfilePathInfoTask . Wait ( ) ;
return true ;
}
catch ( Exception ex )
{
Console . WriteLine ( $"ShortcutRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
return false ;
}
}
private static void ApplyTopology ( ProfileItem profile )
{
Debug . Print ( "ShortcutRepository.ApplyTopology()" ) ;
if ( profile = = null )
return ;
try
{
var surroundTopologies =
profile . Viewports . SelectMany ( viewport = > viewport . TargetDisplays )
. Select ( target = > target . SurroundTopology )
. Where ( topology = > topology ! = null )
. Select ( topology = > topology . ToGridTopology ( ) )
. ToArray ( ) ;
if ( surroundTopologies . Length = = 0 )
{
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 ( ) ;
}
}
if ( surroundTopologies . Length > 0 )
{
GridTopology . SetGridTopologies ( surroundTopologies , SetDisplayTopologyFlag . MaximizePerformance ) ;
}
}
catch ( Exception ex )
{
Console . WriteLine ( $"ShortcutRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
// ignored
}
}
private static void ApplyPathInfo ( ProfileItem profile )
{
Debug . Print ( "ShortcutRepository.ApplyPathInfo()" ) ;
if ( profile = = null )
return ;
if ( ! profile . IsPossible )
{
throw new InvalidOperationException (
$"ShortcutRepository/ApplyPathInfo exception: Problem applying the '{profile.Name}' Display Profile! The display configuration changed since this profile is created. Please re-create this profile." ) ;
}
var pathInfos = profile . Viewports . Select ( viewport = > viewport . ToPathInfo ( ) ) . Where ( info = > info ! = null ) . ToArray ( ) ;
WindowsDisplayAPI . DisplayConfig . PathInfo . ApplyPathInfos ( pathInfos , true , true , true ) ;
}
2020-07-23 06:31:00 +00:00
2020-06-14 04:20:52 +00:00
public static bool IsValidFilename ( string testName )
{
string strTheseAreInvalidFileNameChars = new string ( Path . GetInvalidFileNameChars ( ) ) ;
Regex regInvalidFileName = new Regex ( "[" + Regex . Escape ( strTheseAreInvalidFileNameChars ) + "]" ) ;
if ( regInvalidFileName . IsMatch ( testName ) ) { return false ; } ;
return true ;
}
public static string GetValidFilename ( string uncheckedFilename )
{
string invalid = new string ( Path . GetInvalidFileNameChars ( ) ) + new string ( Path . GetInvalidPathChars ( ) ) ;
foreach ( char c in invalid )
{
uncheckedFilename = uncheckedFilename . Replace ( c . ToString ( ) , "" ) ;
}
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 ) { }
}
}