Skip to content

Commit

Permalink
Added logic to show command line parser help text in console when "--…
Browse files Browse the repository at this point in the history
…help" argument is specified
  • Loading branch information
Atria1234 committed Jan 17, 2022
1 parent 0db494b commit 5a28551
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 11 deletions.
15 changes: 13 additions & 2 deletions AnnoDesigner/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public static string ApplicationPath
}
}

public static object StartupArguments { get; private set; }
public static IProgramArgs StartupArguments { get; private set; }

/// <summary>
/// The DPI information for the current monitor.
Expand All @@ -132,7 +132,18 @@ public static string ApplicationPath

private async void Application_Startup(object sender, StartupEventArgs e)
{
StartupArguments = ArgumentParser.Parse(e.Args);
try
{
StartupArguments = ArgumentParser.Parse(e.Args);
}
catch (HelpException ex)
{
ConsoleManager.Show();
Console.WriteLine(ex.HelpText);
Console.WriteLine("Press enter to exit");
Console.ReadLine();
Environment.Exit(0);
}

using var mutexAnnoDesigner = new Mutex(true, MutexHelper.MUTEX_ANNO_DESIGNER, out var createdNewMutex);
//Are there other processes still running?
Expand Down
40 changes: 31 additions & 9 deletions AnnoDesigner/ArgumentParser.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using CommandLine;
using CommandLine.Text;

namespace AnnoDesigner
{
[Verb("askAdmin")]
public class AdminRestartArgs
public interface IProgramArgs { }

[Verb("askAdmin", Hidden = true)]
public class AdminRestartArgs : IProgramArgs
{
public const string Arguments = "askAdmin";
}

[Verb("open")]
public class OpenArgs
[Verb("open", HelpText = "Opens layout after AnnoDesigner starts")]
public class OpenArgs : IProgramArgs
{
[Value(0, HelpText = "Input AD file", Required = true)]
public string Filename { get; set; }
}

[Verb("export")]
public class ExportArgs
[Verb("export", HelpText = "Exports layout to image and exits")]
public class ExportArgs : IProgramArgs
{
[Value(0, HelpText = "Input AD file", Required = true)]
public string Filename { get; set; }
Expand Down Expand Up @@ -59,11 +63,29 @@ public class ExportArgs
public bool RenderVersion { get; set; }
}

public class HelpException : Exception
{
public HelpText HelpText { get; }

public HelpException(HelpText helpText)
{
HelpText = helpText;
}
}

public static class ArgumentParser
{
public static object Parse(IEnumerable<string> arguments)
public static IProgramArgs Parse(IEnumerable<string> arguments)
{
return Parser.Default.ParseArguments<AdminRestartArgs, OpenArgs, ExportArgs>(arguments).MapResult(x => x, _ => null);
var parsed = Parser.Default.ParseArguments<AdminRestartArgs, OpenArgs, ExportArgs>(arguments);
return parsed.MapResult<AdminRestartArgs, OpenArgs, ExportArgs, IProgramArgs>(x => x, x => x, x => x, errors =>
{
if (errors.IsHelp() || errors.IsVersion())
{
throw new HelpException(HelpText.AutoBuild(parsed));
}
return null;
});
}
}
}
92 changes: 92 additions & 0 deletions AnnoDesigner/ConsoleManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;

namespace AnnoDesigner
{
/// <summary>
/// Console manager class for showing console when help text should be shown.
/// </summary>
/// <remarks>
/// Source: https://stackoverflow.com/a/718505
/// </remarks>
[SuppressUnmanagedCodeSecurity]
public static class ConsoleManager
{
private const string Kernel32_DllName = "kernel32.dll";

[DllImport(Kernel32_DllName)]
private static extern bool AllocConsole();

[DllImport(Kernel32_DllName)]
private static extern bool FreeConsole();

[DllImport(Kernel32_DllName)]
private static extern IntPtr GetConsoleWindow();

[DllImport(Kernel32_DllName)]
private static extern int GetConsoleOutputCP();

public static bool HasConsole
{
get { return GetConsoleWindow() != IntPtr.Zero; }
}

/// <summary>
/// Creates a new console instance if the process is not attached to a console already.
/// </summary>
public static void Show()
{
if (!HasConsole)
{
AllocConsole();
InvalidateOutAndError();
}
}

/// <summary>
/// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown.
/// </summary>
public static void Hide()
{
if (HasConsole)
{
SetOutAndErrorNull();
FreeConsole();
}
}

public static void Toggle()
{
if (HasConsole)
{
Hide();
}
else
{
Show();
}
}

static void InvalidateOutAndError()
{
var type = typeof(Console);

type.GetField("_out", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, null);

type.GetField("_error", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, null);

type.GetMethod("InitializeStdOutError", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.Invoke(null, new object[] { true });
}

static void SetOutAndErrorNull()
{
Console.SetOut(TextWriter.Null);
Console.SetError(TextWriter.Null);
}
}
}
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ The **Anno Designer** is a standalone windows application that can be used for c

**Download the latest version from the [here](https://github.com/AnnoDesigner/anno-designer/releases/tag/AnnoDesignerv9.2)** (select the .exe file). Run it, and use it to design layouts!

Anno Designer can be started either without any arguments or by specifying one of supported verbs. When started without arguments, empty layout is open.

Run `AnnoDesigner.exe --help` for list of supported verbs

- `open` - opens specified layout file instead of empty layout
- `export` - exports specific layout file to PNG file and exits

Run `AnnoDesigner.exe <verb> --help` (for example `AnnoDesigner.exe open --help`) for more info about that verb and its arguments.


## Technology

This application is written in C# (.NET Framework 4.8) and uses WPF.
Expand Down

0 comments on commit 5a28551

Please sign in to comment.