diff --git a/HeliosDisplayManagement/CommandLineOptions.cs b/HeliosDisplayManagement/CommandLineOptions.cs index ccd7cfb..c4e4da4 100644 --- a/HeliosDisplayManagement/CommandLineOptions.cs +++ b/HeliosDisplayManagement/CommandLineOptions.cs @@ -1,29 +1,39 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Windows.Forms; -//using CommandLine; -//using CommandLine.Text; -using HeliosDisplayManagement.Resources; +using CommandLine; +using CommandLine.Text; using HeliosDisplayManagement.Shared; -using System.Runtime.CompilerServices; +using System.Windows.Forms; namespace HeliosDisplayManagement { - internal class CommandLineOptions + class CommandLineOptions { - private CommandLineOptions() - { - } - public static HeliosStartupAction Action { get; set; } - public static string ExecuteArguments { get; set; } - public static string ExecuteFilename { get; set; } - public static string ExecuteProcessName { get; set; } - public static uint ExecuteProcessTimeout { get; set; } - public static uint ExecuteSteamApp { get; set; } - public static string ProfileId { get; set; } - + [Option('a', "action", Default = HeliosStartupAction.None, Required = true, HelpText = "The startup action to perform: None (Show Helios Display Management), SwitchProfile (Change to another profile and optionally run an application/game), CreateShortcut (Create a Desktop Shortcut), EditProfile (Edit a profile)")] + public HeliosStartupAction Action { get; set; } + + [Option('p', "profile", Required = true, HelpText = "The Profile Name or Profile ID of the profile to you want to use.")] + public string Profile { get; set; } + + [Option('e', "execute", SetName = "ByExecutable", Required = false, HelpText = "(optional) The application/game to start when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut. Cannot be used with --steam or --uplay options.")] + public string ExecuteFilename { get; set; } + + [Option('w', "waitfor", SetName = "ByExecutable", Required = false, HelpText = "The process name to wait for when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut. Cannot be used with --steam or --uplay options.")] + public string ExecuteProcessName { get; set; } + + [Option('s', "steam", SetName = "ByGameId", Required = false, HelpText = "The Steam AppID to run for when we're temporarily switching profile and running the Steam application/game. Also can be used when creating a shortcut. Cannot be used with -e or -w options.")] + public uint ExecuteSteamApp { get; set; } + + [Option("uplay", SetName = "ByGameId", Required = false, HelpText = "(optional)The Uplay AppID to run for when we're temporarily switching profile and running the Uplay application/game. Also can be used when creating a shortcut. Cannot be used with -e or -w options.")] + public uint ExecuteUplayApp { get; set; } + + [Option('t', "timeout", Default = 30u, Required = false, HelpText = "(optional) The time in seconds we should delay starting the application/game when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut.")] + public uint ExecuteProcessTimeout { get; set; } + + [Option("arguments", Required = false, HelpText = "(optional) Extra arguments to pass to the application/game when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut.")] + public string ExecuteArguments { get; set; } + + + } } \ No newline at end of file diff --git a/HeliosDisplayManagement/HeliosDisplayManagement.csproj b/HeliosDisplayManagement/HeliosDisplayManagement.csproj index 2af18db..c19455d 100644 --- a/HeliosDisplayManagement/HeliosDisplayManagement.csproj +++ b/HeliosDisplayManagement/HeliosDisplayManagement.csproj @@ -79,6 +79,8 @@ True Language.resx + + @@ -177,6 +179,9 @@ 2.7.0.7 + + 2.7.82 + 1.11.23 @@ -186,12 +191,6 @@ 12.0.3 - - 2.0.0-beta1.20158.1 - - - 0.3.0-alpha.20158.1 - 1.3.0.13 diff --git a/HeliosDisplayManagement/Program.cs b/HeliosDisplayManagement/Program.cs index 1de3f2b..9f4f88e 100644 --- a/HeliosDisplayManagement/Program.cs +++ b/HeliosDisplayManagement/Program.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Invocation; -//using System.CommandLine.DragonFruit; +using CommandLine; +using CommandLine.Text; using System.Diagnostics; using System.IO; using System.Linq; @@ -15,7 +14,9 @@ using HeliosDisplayManagement.InterProcess; using HeliosDisplayManagement.Resources; using HeliosDisplayManagement.Shared; using HeliosDisplayManagement.Steam; +using HeliosDisplayManagement.Uplay; using HeliosDisplayManagement.UIForms; +using System.Net.NetworkInformation; namespace HeliosDisplayManagement { @@ -64,7 +65,7 @@ namespace HeliosDisplayManagement } } - private static void CreateShortcut(IReadOnlyList profiles, int profileIndex) + private static void CreateShortcut(IReadOnlyList profiles, int profileIndex, CommandLineOptions options) { if (profileIndex < 0) { @@ -74,15 +75,15 @@ namespace HeliosDisplayManagement IPCService.GetInstance().Status = InstanceStatus.User; new ShortcutForm(profiles[profileIndex]) { - FileName = CommandLineOptions.ExecuteFilename, - SteamAppId = CommandLineOptions.ExecuteSteamApp, - Arguments = CommandLineOptions.ExecuteArguments, - ProcessName = CommandLineOptions.ExecuteProcessName, - Timeout = CommandLineOptions.ExecuteProcessTimeout + FileName = options.ExecuteFilename, + SteamAppId = options.ExecuteSteamApp, + Arguments = options.ExecuteArguments, + ProcessName = options.ExecuteProcessName, + Timeout = options.ExecuteProcessTimeout }.ShowDialog(); } - private static void EditProfile(IList profiles, int profileIndex) + private static void EditProfile(IList profiles, int profileIndex, CommandLineOptions options) { if (profileIndex < 0) { @@ -110,156 +111,124 @@ namespace HeliosDisplayManagement [STAThread] private static int Main(string[] args) { - var cmd = new RootCommand(); - cmd.Description = "This is an application and things."; - cmd.Add(new Option( - aliases: new string[] {"--action", "-a"}, - getDefaultValue :() => HeliosStartupAction.None, - description: "(required) The startup action to perform: None (Do nothing), SwitchProfile (Change to another profile and optionally run an application/game), CreateShortcut (Create a Desktop Shortcut), EditProfile (Edit a profile)" - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--profile-id", "-p" }, - description: "(required) UUID string that selects the profile to use." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--arguments" }, - description: "(optional) Extra arguments to pass to the application/game when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--execute", "-e" }, - description: "(optional) The application/game to start when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--waitfor", "-w" }, - description: "(optional) The process name to wait for when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--timeout", "-t" }, - description: "(optional) The time in seconds we should delay starting the application/game when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--steam", "-s" }, - description: "(optional)The Steam AppID to run for when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - /*cmd.Add(new Option( - aliases: new string[] { "--uplay" }, - description: "(optional)The Uplay ID to run when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--epic" }, - description: "(optional)The Epic ID to run when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - ); - cmd.Add(new Option( - aliases: new string[] { "--origin" }, - description: "(optional)The Origin ID to run when we're temporarily switching profile and running the application/game. Also can be used when creating a shortcut." - ) - );*/ - - cmd.Handler = CommandHandler.Create((action, profileId, arguments, execute, waitfor, timeout, steam) => - { - - // Validate combinations of Command line options - // If a profileId is supplied then we need an action other than None - if (action == HeliosStartupAction.None && !String.IsNullOrEmpty(profileId)) - { - Console.WriteLine("Error - If you supply a Profile ID or Name then you must also provide an Action."); - return 1; - } - - //var help = new System.CommandLine.Help.HelpBuilder(invocationContext.Console); - //Console.WriteLine(help); - - - // Save these in CommandLineOptions for easy access from other parts of the application - CommandLineOptions.Action = action; - CommandLineOptions.ProfileId = profileId; - CommandLineOptions.ExecuteArguments = arguments; - CommandLineOptions.ExecuteFilename = execute; - CommandLineOptions.ExecuteProcessName = waitfor; - CommandLineOptions.ExecuteProcessTimeout = timeout; - CommandLineOptions.ExecuteSteamApp = steam; - - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - - try - { - if (!IPCService.StartService()) - { - throw new Exception(Language.Can_not_open_a_named_pipe_for_Inter_process_communication); - } - - // Create an array of profiles - var profiles = Profile.GetAllProfiles().ToArray(); - // Show the user the profiles if they want to look - foreach (Profile profile in profiles) - { - Console.WriteLine($"Found Profile: {profile.Name} (ID:{profile.Id})"); - } - // Try and lookup the profileId in the profileIndex - var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Id.Equals(CommandLineOptions.ProfileId, StringComparison.InvariantCultureIgnoreCase)) : -1; - // If the profileID wasn't there, maybe they used the profile name? - if (profileIndex == -1) - { - profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Name.Equals(CommandLineOptions.ProfileId, StringComparison.InvariantCultureIgnoreCase)) : -1; - } - Console.WriteLine($"Using Profile: {profiles[profileIndex].Name} (ID:{profiles[profileIndex].Id})"); - - - switch (CommandLineOptions.Action) - { - case HeliosStartupAction.SwitchProfile: - SwitchProfile(profiles, profileIndex); - - break; - case HeliosStartupAction.EditProfile: - EditProfile(profiles, profileIndex); - - break; - case HeliosStartupAction.CreateShortcut: - CreateShortcut(profiles, profileIndex); - - break; - default: - IPCService.GetInstance().Status = InstanceStatus.User; - Application.Run(new MainForm()); - - break; - } - - - } - catch (Exception e) - { - MessageBox.Show( - string.Format(Language.Operation_Failed, e.Message), - Language.Fatal_Error, - MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - return 0; - }); - - var result = cmd.InvokeAsync(args).Result; + /*return Parser.Default.ParseArguments(args).MapResult( + options => RunOptions(options), + _ => 1);*/ + //var parser = new CommandLine.Parser(with => with.HelpWriter = null); + //var parserResult = parser.ParseArguments(args) + var result = Parser.Default.ParseArguments(args) + .MapResult( + options => RunOptions(options), + _ => 1); return result; - - } + static void DisplayHelp(ParserResult result, IEnumerable errs) + { + var helpText = HelpText.AutoBuild(result, h => + { + h.AdditionalNewLineAfterOption = false; + h.Heading = "Myapp 2.0.0-beta"; //change header + h.Copyright = "Copyright (c) 2019 Global.com"; //change copyright text + return HelpText.DefaultParsingErrorsHandler(result, h); + }, e => e); + Console.WriteLine(helpText); + } + + static int RunOptions(CommandLineOptions options) + { + // Validate combinations of Command line options + // If a profileId is supplied then we need an action other than None + if (options.Action == HeliosStartupAction.None && !String.IsNullOrEmpty(options.Profile)) + { + Console.WriteLine("Error - If you supply a Profile ID or Name then you must also provide an Action."); + return 1; + } + + Console.WriteLine(CommandLine.Parser.Default.FormatCommandLine(options)); + + if (options.Action != HeliosStartupAction.None && String.IsNullOrEmpty(options.Profile)) + { + Console.WriteLine("Error - If you want to perform an Action then you must also provide a Profile ID or Name."); + return 1; + } + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + + try + { + if (!IPCService.StartService()) + { + throw new Exception(Language.Can_not_open_a_named_pipe_for_Inter_process_communication); + } + + // Create an array of profiles + var profiles = Profile.GetAllProfiles().ToArray(); + // Show the user the profiles if they want to look + foreach (Profile aprofile in profiles) + { + Console.WriteLine($"Found Profile: {aprofile.Name} (ID:{aprofile.Id})"); + } + // Try and lookup the profile in the profiles' ID fields + var profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Id.Equals(options.Profile, StringComparison.InvariantCultureIgnoreCase)) : -1; + // If the profileID wasn't there, maybe they used the profile name? + if (profileIndex == -1) + { + // Try and lookup the profile in the profiles' Name fields + profileIndex = profiles.Length > 0 ? Array.FindIndex(profiles, p => p.Name.Equals(options.Profile, StringComparison.InvariantCultureIgnoreCase)) : -1; + } + // If the profileID still isn't there, then raise the alarm + if (profileIndex == -1) + { + Console.WriteLine($"Error - Couldn't find Profile Name or ID supplied via command line: \"{options.Profile}\". Please check the Profile Name or ID you supplied is correct."); + return 1; + } + Console.WriteLine($"Using Profile: {profiles[profileIndex].Name} (ID:{profiles[profileIndex].Id})"); + + + switch (options.Action) + { + case HeliosStartupAction.SwitchProfile: + SwitchProfile(profiles, profileIndex, options); + + break; + case HeliosStartupAction.EditProfile: + EditProfile(profiles, profileIndex, options); + + break; + case HeliosStartupAction.CreateShortcut: + CreateShortcut(profiles, profileIndex, options); + + break; + default: + IPCService.GetInstance().Status = InstanceStatus.User; + Application.Run(new MainForm()); + + break; + } + + + } + catch (Exception e) + { + MessageBox.Show( + string.Format(Language.Operation_Failed, e.Message), + Language.Fatal_Error, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + return 0; + } + static void HandleParseError(IEnumerable errs) + { + //handle errors + } // ReSharper disable once CyclomaticComplexity - private static void SwitchProfile(IReadOnlyList profiles, int profileIndex) + private static void SwitchProfile(IReadOnlyList profiles, int profileIndex, CommandLineOptions options) { var rollbackProfile = Profile.GetCurrent(string.Empty); @@ -285,9 +254,9 @@ namespace HeliosDisplayManagement .Another_instance_of_this_program_is_in_working_state_Please_close_other_instances_before_trying_to_switch_profile); } - if (!string.IsNullOrWhiteSpace(CommandLineOptions.ExecuteFilename)) + if (!string.IsNullOrWhiteSpace(options.ExecuteFilename)) { - if (!File.Exists(CommandLineOptions.ExecuteFilename)) + if (!File.Exists(options.ExecuteFilename)) { throw new Exception(Language.Executable_file_not_found); } @@ -297,17 +266,17 @@ namespace HeliosDisplayManagement throw new Exception(Language.Can_not_change_active_profile); } - var process = System.Diagnostics.Process.Start(CommandLineOptions.ExecuteFilename, - CommandLineOptions.ExecuteArguments); + var process = System.Diagnostics.Process.Start(options.ExecuteFilename, + options.ExecuteArguments); var processes = new System.Diagnostics.Process[0]; - if (!string.IsNullOrWhiteSpace(CommandLineOptions.ExecuteProcessName)) + if (!string.IsNullOrWhiteSpace(options.ExecuteProcessName)) { var ticks = 0; - while (ticks < CommandLineOptions.ExecuteProcessTimeout * 1000) + while (ticks < options.ExecuteProcessTimeout * 1000) { - processes = System.Diagnostics.Process.GetProcessesByName(CommandLineOptions.ExecuteProcessName); + processes = System.Diagnostics.Process.GetProcessesByName(options.ExecuteProcessName); if (processes.Length > 0) { @@ -374,9 +343,9 @@ namespace HeliosDisplayManagement } } } - else if (CommandLineOptions.ExecuteSteamApp > 0) + else if (options.ExecuteSteamApp > 0) { - var steamGame = new SteamGame(CommandLineOptions.ExecuteSteamApp); + var steamGame = new SteamGame(options.ExecuteSteamApp); if (!SteamGame.SteamInstalled) { @@ -405,16 +374,16 @@ namespace HeliosDisplayManagement var address = $"steam://rungameid/{steamGame.AppId}"; - if (!string.IsNullOrWhiteSpace(CommandLineOptions.ExecuteArguments)) + if (!string.IsNullOrWhiteSpace(options.ExecuteArguments)) { - address += "/" + CommandLineOptions.ExecuteArguments; + address += "/" + options.ExecuteArguments; } var steamProcess = System.Diagnostics.Process.Start(address); // Wait for steam game to update and then run var ticks = 0; - while (ticks < CommandLineOptions.ExecuteProcessTimeout * 1000) + while (ticks < options.ExecuteProcessTimeout * 1000) { if (steamGame.IsRunning) {