2017-02-26 19:23:31 +00:00
using System ;
using System.Collections.Generic ;
2020-04-19 05:37:29 +00:00
using System.ComponentModel.DataAnnotations ;
using McMaster.Extensions.CommandLineUtils ;
2017-02-26 19:23:31 +00:00
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
2018-10-20 00:20:53 +00:00
using System.Net ;
2020-04-19 05:37:29 +00:00
using System.Reflection ;
2020-04-13 10:10:35 +00:00
using System.Runtime.CompilerServices ;
2017-02-26 19:23:31 +00:00
using System.Threading ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
2020-04-23 08:16:16 +00:00
using HeliosPlus.InterProcess ;
using HeliosPlus.Resources ;
2020-04-27 10:55:44 +00:00
using HeliosPlus.GameLibraries ;
2020-04-23 08:16:16 +00:00
using HeliosPlus.Shared ;
using HeliosPlus.UIForms ;
2020-04-14 10:18:52 +00:00
using System.Net.NetworkInformation ;
2020-05-17 09:19:55 +00:00
using System.Text.RegularExpressions ;
2020-06-14 04:20:52 +00:00
using System.Drawing ;
2017-02-26 19:23:31 +00:00
2020-04-23 08:16:16 +00:00
namespace HeliosPlus {
2020-07-21 11:40:33 +00:00
public enum SupportedProgramMode
{
RunShortcut ,
EditProfile ,
StartUpNormally
}
2020-04-22 11:46:31 +00:00
public enum SupportedGameLibrary
{
Unknown ,
Steam ,
Uplay
}
2017-02-26 19:23:31 +00:00
internal static class Program
{
2020-04-13 03:47:38 +00:00
2020-05-09 13:02:07 +00:00
internal static string AppDataPath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , "HeliosPlus" ) ;
2020-06-14 04:20:52 +00:00
public static string AppIconPath = Path . Combine ( Program . AppDataPath , $"Icons" ) ;
2020-08-18 22:16:04 +00:00
public static string AppProfilePath = Path . Combine ( Program . AppDataPath , $"Profiles" ) ;
public static string AppShortcutPath = Path . Combine ( Program . AppDataPath , $"Shortcuts" ) ;
2020-06-14 04:20:52 +00:00
public static string AppHeliosPlusIconFilename = Path . Combine ( AppIconPath , @"HeliosPlus.ico" ) ;
public static string AppOriginIconFilename = Path . Combine ( AppIconPath , @"Origin.ico" ) ;
public static string AppSteamIconFilename = Path . Combine ( AppIconPath , @"Steam.ico" ) ;
public static string AppUplayIconFilename = Path . Combine ( AppIconPath , @"Steam.ico" ) ;
public static string AppEpicIconFilename = Path . Combine ( AppIconPath , @"Epic.ico" ) ;
2020-05-19 09:41:26 +00:00
//internal static string ShortcutIconCachePath;
2020-04-22 11:46:31 +00:00
2020-05-09 13:02:07 +00:00
2020-07-21 11:40:33 +00:00
2017-02-26 19:23:31 +00:00
/// <summary>
/// The main entry point for the application.
/// </summary>
2020-04-13 10:10:35 +00:00
[STAThread]
private static int Main ( string [ ] args )
2017-02-26 19:23:31 +00:00
{
2020-04-13 10:10:35 +00:00
2020-04-28 10:38:43 +00:00
// Write the Application Name
Console . WriteLine ( $"{Application.ProductName} v{Application.ProductVersion}" ) ;
for ( int i = 0 ; i < = Application . ProductName . Length + Application . ProductVersion . Length ; i + + )
{
Console . Write ( "=" ) ;
}
Console . WriteLine ( "=" ) ;
2020-07-21 11:40:33 +00:00
Console . WriteLine ( $"Copyright <20> Terry MacDonald 2020-{DateTime.Today.Year}" ) ;
2020-04-28 10:38:43 +00:00
Console . WriteLine ( @"Based on Helios Display Management - Copyright <20> Soroush Falahati 2017-2020" ) ;
2020-04-19 05:37:29 +00:00
var app = new CommandLineApplication ( ) ;
2020-04-13 10:10:35 +00:00
2020-04-19 05:37:29 +00:00
//app.Name = "HeliosDM+";
//app.Name = Assembly.GetEntryAssembly().GetName().Name;
app . Description = "This application helps configure your NVIDIA Videocard for multiple displays." ;
app . ExtendedHelpText = "This application helps configure your NVIDIA Videocard for multiple displays. It has some nifty features such as the "
+ Environment . NewLine + " ability to temporarily change your screen settings while you are playing a game, and then change them back once finished." ;
2017-02-26 19:23:31 +00:00
2020-04-19 05:37:29 +00:00
app . GetFullNameAndVersion ( ) ;
app . MakeSuggestionsInErrorMessage = true ;
2020-04-28 10:38:43 +00:00
app . HelpOption ( "-?|-h|--help" , inherited : true ) ;
2020-04-16 10:49:11 +00:00
2020-04-19 05:37:29 +00:00
app . VersionOption ( "-v|--version" , ( ) = > {
return string . Format ( "Version {0}" , Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ) ;
} ) ;
2020-04-13 10:10:35 +00:00
2020-07-21 11:40:33 +00:00
// This is the RunShortcut command
app . Command ( SupportedProgramMode . RunShortcut . ToString ( ) , ( switchProfileCmd ) = >
2020-04-14 10:18:52 +00:00
{
2020-07-21 11:40:33 +00:00
var argumentShortcut = switchProfileCmd . Argument ( "\"SHORTCUT_UUID\"" , "(required) The UUID of the shortcut to run from those stored in the shortcut library." ) . IsRequired ( ) ;
2020-05-17 09:19:55 +00:00
argumentShortcut . Validators . Add ( new ShortcutMustExistValidator ( ) ) ;
2020-04-19 05:37:29 +00:00
//description and help text of the command.
2020-07-21 11:40:33 +00:00
switchProfileCmd . Description = "Use this command to run favourite game or application with a display profile of your choosing." ;
2018-10-20 00:27:25 +00:00
2020-04-28 10:38:43 +00:00
switchProfileCmd . OnExecute ( ( ) = >
2020-04-19 05:37:29 +00:00
{
2020-07-21 11:40:33 +00:00
//
RunShortcut ( argumentShortcut . Value ) ;
2020-05-17 09:19:55 +00:00
return 0 ;
2020-04-19 05:37:29 +00:00
} ) ;
} ) ;
2020-07-21 11:40:33 +00:00
/ * // This is the EditProfile command
app . Command ( SupportedProgramMode . EditProfile . ToString ( ) , ( editProfileCmd ) = >
2020-04-19 05:37:29 +00:00
{
//description and help text of the command.
2020-04-28 10:38:43 +00:00
editProfileCmd . Description = "Use this command to edit a HeliosDMPlus profile." ;
2020-04-19 05:37:29 +00:00
2020-04-28 10:38:43 +00:00
var optionProfile = editProfileCmd . Option ( "-p|--profile" , "The Profile Name or Profile ID of the profile to you want to use." , CommandOptionType . SingleValue ) . IsRequired ( ) ;
optionProfile . Validators . Add ( new ProfileMustExistValidator ( ) ) ;
editProfileCmd . OnExecute ( ( ) = >
2020-04-19 05:37:29 +00:00
{
Console . WriteLine ( $"Editing profile {optionProfile.Value()}" ) ;
EditProfile (
GetProfile ( optionProfile . Value ( ) )
) ;
return 0 ;
} ) ;
2020-07-21 11:40:33 +00:00
} ) ; * /
2020-04-19 05:37:29 +00:00
2020-04-22 11:46:31 +00:00
app . OnExecute ( ( ) = >
{
Console . WriteLine ( "Starting Normally..." ) ;
StartUpNormally ( ) ;
return 0 ;
} ) ;
2020-04-19 05:37:29 +00:00
try
{
// This begins the actual execution of the application
app . Execute ( args ) ;
}
catch ( CommandParsingException ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"Program/Main commandParsingException: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-04-19 05:37:29 +00:00
// You'll always want to catch this exception, otherwise it will generate a messy and confusing error for the end user.
// the message will usually be something like:
// "Unrecognized command or argument '<invalid-command>'"
Console . WriteLine ( ex . Message ) ;
}
catch ( Exception ex )
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"Program/Main exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-04-19 05:37:29 +00:00
Console . WriteLine ( "Unable to execute application: {0}" , ex . Message ) ;
}
return 0 ;
//return app.Execute(args);
}
private static void StartUpNormally ( )
{
Application . EnableVisualStyles ( ) ;
Application . SetCompatibleTextRenderingDefault ( false ) ;
ServicePointManager . SecurityProtocol = SecurityProtocolType . Tls12 ;
try
{
// Start the IPC Service to
if ( ! IPCService . StartService ( ) )
{
throw new Exception ( Language . Can_not_open_a_named_pipe_for_Inter_process_communication ) ;
2017-02-26 19:23:31 +00:00
}
2020-04-13 03:47:38 +00:00
2020-08-18 22:16:04 +00:00
// Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program
if ( ! Directory . Exists ( AppIconPath ) )
{
try
{
Directory . CreateDirectory ( AppIconPath ) ;
}
catch ( Exception ex )
{
Console . WriteLine ( $"Program/StartUpNormally exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
// TODO
}
}
2020-04-13 03:47:38 +00:00
2020-06-14 04:20:52 +00:00
// Create the Shortcut Icon Cache if it doesn't exist so that it's avilable for all the program
if ( ! Directory . Exists ( AppIconPath ) )
{
try
{
Directory . CreateDirectory ( AppIconPath ) ;
}
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 ( $"Program/StartUpNormally exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// TODO
}
}
try
{
// Save a copy of the HeliosPlus Icon, and all the game library ones in preparation for future use
if ( ! File . Exists ( AppHeliosPlusIconFilename ) )
{
Icon heliosIcon = ( Icon ) Properties . Resources . HeliosPlus ;
using ( FileStream fs = new FileStream ( AppHeliosPlusIconFilename , FileMode . Create ) )
heliosIcon . Save ( fs ) ;
}
// Save a copy of the Steam Icon, and all the game library ones in preparation for future use
if ( ! File . Exists ( AppSteamIconFilename ) )
{
Icon heliosIcon = ( Icon ) Properties . Resources . Steam ;
using ( FileStream fs = new FileStream ( AppSteamIconFilename , FileMode . Create ) )
heliosIcon . Save ( fs ) ;
}
// Save a copy of the Uplay Icon, and all the game library ones in preparation for future use
if ( ! File . Exists ( AppUplayIconFilename ) )
{
Icon heliosIcon = ( Icon ) Properties . Resources . Uplay ;
using ( FileStream fs = new FileStream ( AppUplayIconFilename , FileMode . Create ) )
heliosIcon . Save ( fs ) ;
}
// Save a copy of the Epic Icon, and all the game library ones in preparation for future use
if ( ! File . Exists ( AppEpicIconFilename ) )
{
Icon heliosIcon = ( Icon ) Properties . Resources . Epic ;
using ( FileStream fs = new FileStream ( AppEpicIconFilename , FileMode . Create ) )
heliosIcon . Save ( fs ) ;
}
// Save a copy of the Origin Icon, and all the game library ones in preparation for future use
if ( ! File . Exists ( AppOriginIconFilename ) )
{
Icon heliosIcon = ( Icon ) Properties . Resources . Origin ;
using ( FileStream fs = new FileStream ( AppOriginIconFilename , FileMode . Create ) )
heliosIcon . Save ( fs ) ;
}
}
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 ( $"Program/StartUpNormally exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-06-14 04:20:52 +00:00
// TODO
}
2020-04-19 05:37:29 +00:00
IPCService . GetInstance ( ) . Status = InstanceStatus . User ;
2020-05-03 08:39:35 +00:00
Application . Run ( new UIForms . MainForm ( ) ) ;
2020-04-19 05:37:29 +00:00
2020-04-14 10:18:52 +00:00
}
2020-05-19 09:41:26 +00:00
catch ( Exception ex )
2020-04-14 10:18:52 +00:00
{
2020-07-24 04:51:48 +00:00
Console . WriteLine ( $"Program/StartUpNormally exception 3: {ex.Message}: {ex.StackTrace} - {ex.InnerException}" ) ;
2020-04-14 10:18:52 +00:00
MessageBox . Show (
2020-05-19 09:41:26 +00:00
ex . Message ,
2020-04-14 10:18:52 +00:00
Language . Fatal_Error ,
MessageBoxButtons . OK ,
MessageBoxIcon . Error ) ;
}
2020-04-16 10:49:11 +00:00
2020-04-14 10:18:52 +00:00
}
2020-04-13 10:10:35 +00:00
2018-10-20 00:27:25 +00:00
2020-07-21 11:40:33 +00:00
// ReSharper disable once CyclomaticComplexity
private static void RunShortcut ( string shortcutUUID )
{
ShortcutItem shortcutToRun = null ;
2018-10-20 00:27:25 +00:00
2020-07-21 11:40:33 +00:00
// Check there is only one version of this application so we won't
// mess with another monitoring session
2017-02-26 19:23:31 +00:00
if (
IPCClient . QueryAll ( )
. Any (
client = >
2018-10-20 00:27:25 +00:00
client . Status = = InstanceStatus . Busy | |
client . Status = = InstanceStatus . OnHold ) )
{
2017-02-26 19:23:31 +00:00
throw new Exception (
Language
. Another_instance_of_this_program_is_in_working_state_Please_close_other_instances_before_trying_to_switch_profile ) ;
2018-10-20 00:27:25 +00:00
}
2020-07-21 11:40:33 +00:00
// Match the ShortcutName to the actual shortcut listed in the shortcut library
// And error if we can't find it.
if ( ShortcutRepository . ContainsShortcut ( shortcutUUID ) )
2017-02-26 19:23:31 +00:00
{
2020-07-21 11:40:33 +00:00
// make sure we trim the "" if there are any
shortcutUUID = shortcutUUID . Trim ( '"' ) ;
shortcutToRun = ShortcutRepository . GetShortcut ( shortcutUUID ) ;
2020-04-19 05:37:29 +00:00
}
2020-07-21 11:40:33 +00:00
else
2020-04-19 05:37:29 +00:00
{
2020-07-21 11:40:33 +00:00
throw new Exception ( Language . Cannot_find_shortcut_in_library ) ;
2020-04-19 05:37:29 +00:00
}
2018-10-20 00:27:25 +00:00
2020-07-23 06:31:00 +00:00
if ( shortcutToRun is ShortcutItem )
2020-04-19 05:37:29 +00:00
{
2020-07-23 06:31:00 +00:00
ShortcutRepository . RunShortcut ( shortcutToRun ) ;
2020-04-19 05:37:29 +00:00
}
2018-10-20 00:27:25 +00:00
2020-07-21 11:40:33 +00:00
IPCService . GetInstance ( ) . Status = InstanceStatus . Busy ;
2020-04-19 05:37:29 +00:00
}
2020-07-23 06:31:00 +00:00
/ * private static void EditProfile ( ProfileItem profile )
2020-04-19 05:37:29 +00:00
{
2020-07-21 11:40:33 +00:00
// Get the status of the thing
IPCService . GetInstance ( ) . Status = InstanceStatus . User ;
// Load all the profiles from JSON
//ProfileRepository.AllProfiles
// Start up the DisplayProfileForm directly
new DisplayProfileForm ( profile ) . ShowDialog ( ) ;
// Then we close down as we're only here to edit one profile
Application . Exit ( ) ;
2017-02-26 19:23:31 +00:00
}
2020-07-23 06:31:00 +00:00
* /
2020-05-17 09:19:55 +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 ;
}
2020-07-23 06:31:00 +00:00
/ * public static string GetValidFilename ( string uncheckedFilename )
2020-05-17 09:19:55 +00:00
{
string invalid = new string ( Path . GetInvalidFileNameChars ( ) ) + new string ( Path . GetInvalidPathChars ( ) ) ;
foreach ( char c in invalid )
{
uncheckedFilename = uncheckedFilename . Replace ( c . ToString ( ) , "" ) ;
}
return uncheckedFilename ;
2020-07-23 06:31:00 +00:00
} * /
2017-02-26 19:23:31 +00:00
}
}