Support for command line arguments (#155)

This commit is contained in:
2023-06-18 18:02:02 +08:00
parent aabe6664b4
commit b2b656b6cb
5 changed files with 244 additions and 8 deletions

View File

@@ -0,0 +1,64 @@
using System;
using System.Runtime.InteropServices;
namespace GrasscutterTools.Utils
{
/// <summary>
/// <see cref="https://stackoverflow.com/a/17534263"/>
/// </summary>
public class GuiRedirect
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(StandardHandle nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern FileType GetFileType(IntPtr handle);
//[DllImport("kernel32.dll", SetLastError = true)]
//[return: MarshalAs(UnmanagedType.Bool)]
//static extern bool AllocConsole();
private enum StandardHandle : uint
{
Input = unchecked((uint)-10),
Output = unchecked((uint)-11),
Error = unchecked((uint)-12)
}
private enum FileType : uint
{
Unknown = 0x0000,
Disk = 0x0001,
Char = 0x0002,
Pipe = 0x0003
}
private static bool IsRedirected(IntPtr handle)
{
FileType fileType = GetFileType(handle);
return (fileType == FileType.Disk) || (fileType == FileType.Pipe);
}
public static void Redirect()
{
if (IsRedirected(GetStdHandle(StandardHandle.Output)))
{
var initialiseOut = Console.Out;
}
bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error));
if (errorRedirected)
{
var initialiseError = Console.Error;
}
AttachConsole(-1);
if (!errorRedirected)
SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output));
}
}
}

View File

@@ -25,16 +25,17 @@ namespace GrasscutterTools.Utils
{
public static class Logger
{
public static bool IsSaveLogs = false;
private static readonly string LogPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), $"GcTools-{DateTime.Now:MMdd}.log");
private static void Write(string message)
{
#if DEBUG
Console.WriteLine($"{DateTime.Now:mm:ss.fff} {message}");
#else
// Test log
//File.AppendAllText(LogPath, $"{DateTime.Now:mm:ss.fff} {message}{Environment.NewLine}");
#endif
if (IsSaveLogs)
{
Console.WriteLine($"{DateTime.Now:mm:ss.fff} {message}");
File.AppendAllText(LogPath, $"{DateTime.Now:mm:ss.fff} {message}{Environment.NewLine}");
}
}
private static void Write(string level, string tag, string message) => Write($"<{level}:{tag}> {message}");

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace GrasscutterTools.Utils
{
/// <summary>
/// Simple command line toggles parser:
/// - toggles are identified with (any number of) '-' prefixes
/// - toggle can be with or without associated value
/// - toggles are case-insensitive
///
/// <example>--toggle_without_value -toggle value</example>
/// <see cref="https://gist.github.com/jchapuis/64b5adf9d0f3062e6a72dded110a6028"/>
/// </summary>
internal class ToggleParser
{
private readonly Dictionary<string, string> toggles;
public ToggleParser(string[] args)
{
toggles =
args.Zip(args.Skip(1).Concat(new[] { string.Empty }), (first, second) => new { first, second })
.Where(pair => IsToggle(pair.first))
.ToDictionary(pair => RemovePrefix(pair.first).ToLowerInvariant(), g => IsToggle(g.second) ? string.Empty : g.second);
}
private static string RemovePrefix(string toggle)
=> new string(toggle.SkipWhile(c => c == '-').ToArray());
private static bool IsToggle(string arg)
=> arg.StartsWith("-", StringComparison.InvariantCulture);
public bool HasToggle(string toggle)
=> toggles.ContainsKey(toggle.ToLowerInvariant());
public string GetToggleValueOrDefault(string toggle, string defaultValue)
=> toggles.TryGetValue(toggle.ToLowerInvariant(), out var value) ? value : defaultValue;
public bool IsEmpty => toggles.Count == 0;
}
}