Added .NET Framework 4 target for application

Update ErrorCodes.cs, NibblePoker.Application.ListComPort.csproj, and 2 more files...
This commit is contained in:
2024-05-24 16:49:02 +02:00
parent 6e4462c8fa
commit 60a7cb0f6b
4 changed files with 256 additions and 214 deletions
@@ -1,20 +1,20 @@
namespace NibblePoker.Application.ListComPort; namespace NibblePoker.Application.ListComPort {
public static class ErrorCodes {
public const int NoError = 0;
public static class ErrorCodes { /* Fatal errors (1-9) */
public const int NoError = 0; // Not needed in C#
/* Fatal errors (1-9) */ /* Internal argument parser errors (10-19) */
// Not needed in C# public const int ArgumentParsingFailure = 10;
// ArgumentDefinitionFailure = 11 => Cannot happen due to the way options are declared. (Caught in development)
/* Internal argument parser errors (10-19) */ // ArgumentInitFailure = 12 => Cannot happen with "NibblePoker.Library.Arguments".
public const int ArgumentParsingFailure = 10;
// ArgumentDefinitionFailure = 11 => Cannot happen due to the way options are declared. (Caught in development) /* External argument errors (20-29) */
// ArgumentInitFailure = 12 => Cannot happen with "NibblePoker.Library.Arguments". public const int NoPaddingValue = 20;
/* External argument errors (20-29) */ /* Application & System errors (30-39) */
public const int NoPaddingValue = 20; // NoFriendlyNames = 30 => Causes problems with broad-range exit code checks.
public const int NoComPorts = 31;
/* Application & System errors (30-39) */ }
// NoFriendlyNames = 30 => Causes problems with broad-range exit code checks. }
public const int NoComPorts = 31;
}
@@ -2,9 +2,11 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFrameworks>net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks> <TargetFrameworks>net40;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>disable</Nullable>
<RootNamespace>NibblePoker.Application.ListComPort</RootNamespace> <RootNamespace>NibblePoker.Application.ListComPort</RootNamespace>
<AssemblyName>NibblePoker.Application.ListComPort</AssemblyName> <AssemblyName>NibblePoker.Application.ListComPort</AssemblyName>
<AssemblyVersion>4.0.0</AssemblyVersion> <AssemblyVersion>4.0.0</AssemblyVersion>
@@ -14,8 +16,6 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Authors>Herwin Bozet (@NibblePoker)</Authors> <Authors>Herwin Bozet (@NibblePoker)</Authors>
<ApplicationIcon>..\NibblePoker.Packaging.ListComPort\Icons\lscom-v2-text-01.ico</ApplicationIcon> <ApplicationIcon>..\NibblePoker.Packaging.ListComPort\Icons\lscom-v2-text-01.ico</ApplicationIcon>
<Configurations>Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+233 -189
View File
@@ -4,204 +4,248 @@ using System.Linq;
using NibblePoker.Library.Arguments; using NibblePoker.Library.Arguments;
using NibblePoker.Library.ComPortWatcher; using NibblePoker.Library.ComPortWatcher;
namespace NibblePoker.Application.ListComPort; namespace NibblePoker.Application.ListComPort {
internal static class Program {
private const string Version = "4.0.0";
internal static class Program { // ReSharper disable once InconsistentNaming
private const string Version = "4.0.0"; private static readonly Verb RootVerb = new Verb(null);
private static readonly Verb RootVerb = new Verb("");
private static readonly Option OptionShowAll = new('a', "show-all", "Display the complete port's name (Equal to '-dfn')");
private static readonly Option OptionShowDevice = new('d', "show-device", "Displays the port's device name");
private static readonly Option OptionDivider = new('D', "divider", "Uses the given string or char as a separator (Can be an empty string !)", OptionFlags.HasValue);
private static readonly Option OptionShowFriendly = new('f', "show-friendly", "Displays the port's friendly name");
private static readonly Option OptionHelp = new('h', "help", "Display the help text", OptionFlags.StopsParsing);
private static readonly Option OptionHelpShort = new('H', "short-help", "Display the short help text", OptionFlags.StopsParsing);
private static readonly Option OptionShowNameRaw = new('n', "show-name-raw", "Displays the port's raw name (See remarks section)");
private static readonly Option OptionNoPretty = new('P', "no-pretty", "Disables the pretty printing format (Equal to -D \" \"");
private static readonly Option OptionSort = new('s', "sort", "Sorts the port based on their raw names in an ascending order");
private static readonly Option OptionSortReverse = new('S', "sort-reverse", "Sorts the port based on their raw names in a descending order");
private static readonly Option OptionTabPadding = new('t', "tab-padding", "Use tabs for padding between the types of names (Overrides '-D')");
private static readonly Option OptionVersion = new('v', "version", "Shows the utility's version number and other info");
private static readonly Option OptionVersionOnly = new('V', "version-only", "Shows the utility's version number only (Overrides '-v')");
private static bool _shouldPrintRawNames = true;
private static bool _shouldPrintDeviceNames = false;
private static bool _shouldPrintFriendlyNames = false;
private static string _paddingText = "";
private static SortingOrder _sortingOrder = SortingOrder.None; private static readonly Option OptionShowAll = new Option('a', "show-all",
"Display the complete port's name (Equal to '-dfn')");
private static int _exitCode = ErrorCodes.NoError; private static readonly Option OptionShowDevice = new Option('d', "show-device",
"Displays the port's device name");
/// <summary> private static readonly Option OptionShowFriendly = new Option('f', "show-friendly",
/// Checks if the program is the only owner of its console. "Displays the port's friendly name");
/// This check is used to detect if the program was run from the exe/lnk or via a console. private static readonly Option OptionShowNameRaw = new Option('n', "show-name-raw",
/// </summary> "Displays the port's raw name (See remarks section)");
/// <returns><c>True</c> if the process is the console's sole owner, <c>False</c> otherwise</returns>
private static bool IsProgramRunDirectly() {
return GetConsoleProcessList(new int[2], 2) <= 1;
}
private static int Main(string[] args) {
try {
ArgumentsParser.ParseArguments(RootVerb.RegisterOption(OptionShowAll).RegisterOption(OptionShowDevice)
.RegisterOption(OptionDivider).RegisterOption(OptionShowFriendly).RegisterOption(OptionHelp)
.RegisterOption(OptionShowNameRaw).RegisterOption(OptionNoPretty).RegisterOption(OptionSort)
.RegisterOption(OptionSortReverse).RegisterOption(OptionTabPadding).RegisterOption(OptionVersion)
.RegisterOption(OptionVersionOnly), args);
} catch(Exceptions.ArgumentsException) {
Console.Error.WriteLine("Failed to parse the launch arguments, default options will be used.");
_exitCode = ErrorCodes.ArgumentParsingFailure;
RootVerb.Clear();
}
if(OptionHelp.WasUsed() || OptionHelpShort.WasUsed()) { private static readonly Option OptionDivider = new Option('D', "divider",
Console.WriteLine(HelpText.GetFullHelpText(RootVerb, "lscom.exe", (uint)Console.BufferWidth - 1, 1, 2, false)); "Uses the given string or char as a separator (Can be an empty string !)", OptionFlags.HasValue);
private static readonly Option OptionTabPadding = new Option('t', "tab-padding",
if(OptionHelp.WasUsed()) { "Use tabs for padding between the types of names (Overrides '-D')");
Console.WriteLine("\nRemarks:"); private static readonly Option OptionNoPretty = new Option('P', "no-pretty",
Console.WriteLine(" * If '-d' or '-f' is used, the raw name will not be shown unless '-n' is used."); "Disables the pretty printing format (Equal to -D \" \"");
Console.WriteLine(" * If '-D', '-t' or '-p' are used, the special separator between the raw and friendly name and the square brackets are not shown.");
Console.WriteLine(" * If the program is raw without going through a console, the options '-n' and '-f' will be used."); private static readonly Option OptionSort = new Option('s', "sort",
Console.WriteLine(" * By default, the ports are sorted in the order they are provided by the registry, which is often chronological."); "Sorts the port based on their raw names in an ascending order");
Console.WriteLine(" * The 'raw name' refers to a port name. (e.g.: COM1, COM2, ...)"); private static readonly Option OptionSortReverse = new Option('S', "sort-reverse",
Console.WriteLine(" * The 'device name' refers to a port device path. (e.g.: \\Device\\Serial1, ...)"); "Sorts the port based on their raw names in a descending order");
Console.WriteLine(" * The 'friendly name' refers to a port name as seen in the device manager. (e.g.: Communications Port, USB-SERIAL CH340, ...)");
Console.WriteLine(" * Any result returned with an error code between 1-9 and 30-39 should be considered as invalid."); private static readonly Option OptionHelp = new Option('h', "help",
Console.WriteLine(" * Any result returned with another error code is valid but probably not formatted properly."); "Display the help text", OptionFlags.StopsParsing);
private static readonly Option OptionHelpShort = new Option('H', "short-help",
"Display the short help text", OptionFlags.StopsParsing);
private static readonly Option OptionVersion = new Option('v', "version",
"Shows the utility's version number and other info");
private static readonly Option OptionVersionOnly = new Option('V', "version-only",
"Shows the utility's version number only (Overrides '-v')");
// ReSharper disable RedundantDefaultMemberInitializer
private static bool _shouldPrintRawNames = true;
private static bool _shouldPrintDeviceNames = false;
private static bool _shouldPrintFriendlyNames = false;
// ReSharper enable RedundantDefaultMemberInitializer
private static string _paddingText = "";
private static SortingOrder _sortingOrder = SortingOrder.None;
private static int _exitCode = ErrorCodes.NoError;
/// <summary>
/// Checks if the program is the only owner of its console.
/// This check is used to detect if the program was run from the exe/lnk or via a console.
/// </summary>
/// <returns><c>True</c> if the process is the console's sole owner, <c>False</c> otherwise</returns>
private static bool IsProgramRunDirectly() {
return GetConsoleProcessList(new int[2], 2) <= 1;
}
private static int Main(string[] args) {
// Preparing & parsing launch arguments
try {
ArgumentsParser.ParseArguments(RootVerb.RegisterOption(OptionShowAll).RegisterOption(OptionShowDevice)
.RegisterOption(OptionDivider).RegisterOption(OptionShowFriendly).RegisterOption(OptionHelp)
.RegisterOption(OptionShowNameRaw).RegisterOption(OptionNoPretty).RegisterOption(OptionSort)
.RegisterOption(OptionSortReverse).RegisterOption(OptionTabPadding).RegisterOption(OptionVersion)
.RegisterOption(OptionVersionOnly), args);
} catch(Exceptions.ArgumentsException) {
Console.Error.WriteLine("Failed to parse the launch arguments, default options will be used.");
_exitCode = ErrorCodes.ArgumentParsingFailure;
RootVerb.Clear();
} }
return ErrorCodes.NoError; // Processing exiting options
} if(OptionHelp.WasUsed() || OptionHelpShort.WasUsed()) {
Console.WriteLine(HelpText.GetFullHelpText(
if(OptionVersionOnly.WasUsed()) { RootVerb, "lscom.exe",
Console.WriteLine(Version); (uint)Console.BufferWidth - 1, 1, 2, false));
return ErrorCodes.NoError;
} if(OptionHelp.WasUsed()) {
Console.WriteLine("\nRemarks:");
if(OptionVersion.WasUsed()) { Console.WriteLine(
Console.WriteLine("NibblePoker.Application.ListComPort (lscom) v" + Version); " * If '-d' or '-f' is used, the raw name will not be shown unless '-n' is used.");
Console.WriteLine(""); Console.WriteLine(
Console.WriteLine("Dependencies:"); " * If '-D', '-t' or '-p' are used, the special separator between the raw and friendly name and the square brackets are not shown.");
Console.WriteLine("├─> NibblePoker.Library.Arguments v2.0.0"); Console.WriteLine(
Console.WriteLine("├─> NibblePoker.Library.ComPortHelpers v" + Version); " * If the program is raw without going through a console, the options '-n' and '-f' will be used.");
Console.WriteLine("└─> NibblePoker.Library.RegistryHelpers v0.0.1"); Console.WriteLine(
Console.WriteLine(""); " * By default, the ports are sorted in the order they are provided by the registry, which is often chronological.");
Console.WriteLine("GitHub repositories:"); Console.WriteLine(" * The 'raw name' refers to a port name. (e.g.: COM1, COM2, ...)");
Console.WriteLine("├─> https://github.com/aziascreations/DotNet-Arguments"); Console.WriteLine(
Console.WriteLine("├─> https://github.com/aziascreations/DotNet-ListComPort"); " * The 'device name' refers to a port device path. (e.g.: \\Device\\Serial1, ...)");
Console.WriteLine("└─> https://github.com/aziascreations/DotNet-RegistryHelpers"); Console.WriteLine(
Console.WriteLine(""); " * The 'friendly name' refers to a port name as seen in the device manager. (e.g.: Communications Port, USB-SERIAL CH340, ...)");
Console.WriteLine("This software and all its libraries are released in the public domain under the CC0-1.0 license."); Console.WriteLine(
return ErrorCodes.NoError; " * Any result returned with an error code between 1-9 and 30-39 should be considered as invalid.");
} Console.WriteLine(
" * Any result returned with another error code is valid but probably not formatted properly.");
if(OptionShowDevice.WasUsed()) { }
_shouldPrintRawNames = false;
_shouldPrintDeviceNames = true; return ErrorCodes.NoError;
} }
if(OptionShowFriendly.WasUsed() || IsProgramRunDirectly()) { if(OptionVersionOnly.WasUsed()) {
_shouldPrintRawNames = false; Console.WriteLine(Version);
_shouldPrintFriendlyNames = true; return ErrorCodes.NoError;
} }
if(OptionShowNameRaw.WasUsed() || IsProgramRunDirectly()) { if(OptionVersion.WasUsed()) {
_shouldPrintRawNames = true; Console.WriteLine("NibblePoker.Application.ListComPort (lscom) v" + Version);
} Console.WriteLine("");
Console.WriteLine("Dependencies:");
if(OptionShowAll.WasUsed()) { Console.WriteLine("├─> NibblePoker.Library.Arguments v2.0.0");
_shouldPrintRawNames = true; Console.WriteLine("├─> NibblePoker.Library.ComPortHelpers v" + Version);
_shouldPrintFriendlyNames = true; Console.WriteLine("└─> NibblePoker.Library.RegistryHelpers v1.0.0");
_shouldPrintDeviceNames = true; Console.WriteLine("");
} Console.WriteLine("GitHub repositories:");
Console.WriteLine("├─> https://github.com/aziascreations/DotNet-Arguments");
if(OptionSort.WasUsed()) { Console.WriteLine("├─> https://github.com/aziascreations/DotNet-ListComPort");
_sortingOrder = SortingOrder.Ascending; Console.WriteLine("└─> https://github.com/aziascreations/DotNet-RegistryHelpers");
} Console.WriteLine("");
Console.WriteLine(
if(OptionSortReverse.WasUsed()) { "This software and all its libraries are released in the public domain under the CC0-1.0 license.");
_sortingOrder = SortingOrder.Descending; return ErrorCodes.NoError;
} }
if(OptionNoPretty.WasUsed()) { // Processing parameter options
_paddingText = " "; if(OptionShowDevice.WasUsed()) {
} _shouldPrintRawNames = false;
_shouldPrintDeviceNames = true;
if(OptionDivider.WasUsed()) { }
_paddingText = OptionDivider.Arguments[0];
} if(OptionShowFriendly.WasUsed() || IsProgramRunDirectly()) {
_shouldPrintRawNames = false;
if(OptionTabPadding.WasUsed()) { _shouldPrintFriendlyNames = true;
_paddingText = "\t"; }
}
if(OptionShowNameRaw.WasUsed() || IsProgramRunDirectly()) {
// Application's code _shouldPrintRawNames = true;
}
string rawToFriendlySeparator = " - ";
bool addDeviceBrackets = true; if(OptionShowAll.WasUsed()) {
_shouldPrintRawNames = true;
if(string.IsNullOrEmpty(_paddingText)) { _shouldPrintFriendlyNames = true;
_paddingText = " "; _shouldPrintDeviceNames = true;
} else { }
rawToFriendlySeparator = _paddingText;
addDeviceBrackets = false; if(OptionSort.WasUsed()) {
} _sortingOrder = SortingOrder.Ascending;
}
if(!_shouldPrintRawNames && !_shouldPrintFriendlyNames && _shouldPrintDeviceNames) {
addDeviceBrackets = false; if(OptionSortReverse.WasUsed()) {
} _sortingOrder = SortingOrder.Descending;
}
List<ComPortInfo> comPortsInfo = ComPortHelper.GetComList(_shouldPrintFriendlyNames);
if(OptionNoPretty.WasUsed()) {
if(comPortsInfo.Count > 0) { _paddingText = " ";
comPortsInfo = _sortingOrder switch { }
SortingOrder.Ascending => comPortsInfo.OrderBy(o => o.RawName).ToList(),
SortingOrder.Descending => comPortsInfo.OrderByDescending(o => o.RawName).ToList(), if(OptionDivider.WasUsed()) {
_ => comPortsInfo _paddingText = OptionDivider.Arguments[0];
}; }
foreach(ComPortInfo comPortInfo in comPortsInfo) { if(OptionTabPadding.WasUsed()) {
if(_shouldPrintRawNames) { _paddingText = "\t";
Console.Write(comPortInfo.RawName); }
// Application's code
string rawToFriendlySeparator = " - ";
bool addDeviceBrackets = true;
if(string.IsNullOrEmpty(_paddingText)) {
_paddingText = " ";
} else {
rawToFriendlySeparator = _paddingText;
addDeviceBrackets = false;
}
if(!_shouldPrintRawNames && !_shouldPrintFriendlyNames && _shouldPrintDeviceNames) {
addDeviceBrackets = false;
}
List<ComPortInfo> comPortsInfo = ComPortHelper.GetComList(_shouldPrintFriendlyNames);
if(comPortsInfo.Count > 0) {
//comPortsInfo = _sortingOrder switch {
// SortingOrder.Ascending => comPortsInfo.OrderBy(o => o.RawName).ToList(),
// SortingOrder.Descending => comPortsInfo.OrderByDescending(o => o.RawName).ToList(),
// _ => comPortsInfo
//};
switch(_sortingOrder) {
case SortingOrder.Ascending:
comPortsInfo = comPortsInfo.OrderBy(o => o.RawName).ToList();
break;
case SortingOrder.Descending:
comPortsInfo = comPortsInfo.OrderByDescending(o => o.RawName).ToList();
break;
case SortingOrder.None:
default:
break;
}
foreach(ComPortInfo comPortInfo in comPortsInfo) {
if(_shouldPrintRawNames) {
Console.Write(comPortInfo.RawName);
if(_shouldPrintFriendlyNames) {
Console.Write(rawToFriendlySeparator);
}
}
if(_shouldPrintFriendlyNames) { if(_shouldPrintFriendlyNames) {
Console.Write(rawToFriendlySeparator); Console.Write(comPortInfo.FriendlyName);
} }
if((_shouldPrintRawNames || _shouldPrintFriendlyNames) && _shouldPrintDeviceNames) {
Console.Write(_paddingText);
}
if(_shouldPrintDeviceNames) {
Console.Write((addDeviceBrackets ? "[" : "") + comPortInfo.DeviceName +
(addDeviceBrackets ? "]" : ""));
}
Console.WriteLine();
} }
} else {
if(_shouldPrintFriendlyNames) { Console.Error.Write("No COM port could be found.");
Console.Write(comPortInfo.FriendlyName); _exitCode = ErrorCodes.NoComPorts;
}
if((_shouldPrintRawNames || _shouldPrintFriendlyNames) && _shouldPrintDeviceNames) {
Console.Write(_paddingText);
}
if(_shouldPrintDeviceNames) {
Console.Write((addDeviceBrackets ? "[" : "") + comPortInfo.DeviceName + (addDeviceBrackets ? "]" : ""));
}
Console.WriteLine();
} }
} else {
Console.Error.Write("No COM port could be found."); // Allows the program to be run from a shortcut without closing the console instantly.
_exitCode = ErrorCodes.NoComPorts; if(IsProgramRunDirectly()) {
Console.Write("\nPress any key to continue...");
Console.ReadKey();
}
return _exitCode;
} }
// Allows the program to be run from a shortcut without closing the console instantly. // Imports "GetConsoleProcessList(...)" in order to know if the program was run via a shortcut or a CLI prompt.
if(IsProgramRunDirectly()) { // See: https://learn.microsoft.com/en-us/windows/console/getconsoleprocesslist
Console.Write("\nPress any key to continue..."); [System.Runtime.InteropServices.DllImport("kernel32.dll")]
Console.ReadKey(); private static extern int GetConsoleProcessList(int[] buffer, int size);
}
return _exitCode;
} }
// Imports "GetConsoleProcessList(...)" in order to know if the program was run via a shortcut or CLI.
// See: https://learn.microsoft.com/en-us/windows/console/getconsoleprocesslist
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int GetConsoleProcessList(int[] buffer, int size);
} }
@@ -8,8 +8,6 @@
<RootNamespace>NibblePoker.Library.ComPortWatcher</RootNamespace> <RootNamespace>NibblePoker.Library.ComPortWatcher</RootNamespace>
<AssemblyName>NibblePoker.Library.ComPortHelpers</AssemblyName> <AssemblyName>NibblePoker.Library.ComPortHelpers</AssemblyName>
<Configurations>Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>