diff --git a/src/Launch/Options.cs b/src/Launch/Options.cs index 190b3c6..2bdbd83 100644 --- a/src/Launch/Options.cs +++ b/src/Launch/Options.cs @@ -31,5 +31,8 @@ public class Options : IVerb [Option('p', "preview", Required = false, HelpText = "Show me what will launch, but dont run it. This will also report the token values and show the contents of the generated file, if applicable.")] public bool Preview { get; set; } + + [Option("debug", Required = false, HelpText = "Keep the console window visible for troubleshooting.")] + public bool Debug { get; set; } } } diff --git a/src/OneIdentity.Scalus.csproj b/src/OneIdentity.Scalus.csproj index 41e9be5..a665112 100644 --- a/src/OneIdentity.Scalus.csproj +++ b/src/OneIdentity.Scalus.csproj @@ -10,14 +10,14 @@ Exe - net6.0 + net8.0 OneIdentity.Scalus scalus OneIdentity.Scalus.Program false signer.pfx Latest - linux-x64;osx-x64;win10-x64 + linux-x64;osx-x64;win-x64 dc8f57ba-8a9d-40c4-bf34-a2ffba1ff687 One Identity LLC Copyright 2021 One Identity LLC @@ -38,11 +38,11 @@ $(DefineConstants);TRACE - 1701;1702;CA1416 + 1701;1702;CA1416;CA1854;CA1860;CA1865;SYSLIB1045;SYSLIB1054 - 1701;1702;CA1416 + 1701;1702;CA1416;CA1854;CA1860;CA1865;SYSLIB1045;SYSLIB1054 @@ -116,9 +116,9 @@ - + - + @@ -131,7 +131,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/Program.cs b/src/Program.cs index 950c420..4c3219f 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // This software is licensed under the Apache 2.0 open source license. // https://github.com/OneIdentity/SCALUS/blob/master/LICENSE @@ -24,6 +24,7 @@ namespace OneIdentity.Scalus using System; using System.Diagnostics; using System.IO; + using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; @@ -37,8 +38,28 @@ namespace OneIdentity.Scalus internal class Program { + private static bool consoleHidden; + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool FreeConsole(); + private static int Main(string[] args) { + // On Windows, detach from the console for 'launch' and 'ui' verbs so no console + // window is visible. When launched from a browser/Explorer, the console window + // (which was created just for this process) is destroyed. (GitHub issue #131) + // CLI commands (info, register, --help, etc.) keep the console as normal. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && ShouldHideConsole(args)) + { + FreeConsole(); + consoleHidden = true; + + // Redirect stdout/stderr to nowhere so that subsequent Console.WriteLine + // and Serilog console sinks don't throw on the invalid handle. + Console.SetOut(TextWriter.Null); + Console.SetError(TextWriter.Null); + } + bool community = false; #if COMMUNITY_EDITION community = true; @@ -51,7 +72,13 @@ private static int Main(string[] args) try { // Register components with autofac - var logger = new LoggerConfiguration().WriteTo.Console(theme: ConsoleTheme.None).CreateLogger(); + var logConfig = new LoggerConfiguration().WriteTo.File(ConfigurationManager.LogFile, shared: true); + if (!consoleHidden) + { + logConfig.WriteTo.Console(theme: ConsoleTheme.None); + } + + var logger = logConfig.CreateLogger(); using var container = Ioc.RegisterApplication(logger); using var lifetimeScope = container.BeginLifetimeScope(); services = lifetimeScope.Resolve(); @@ -117,6 +144,36 @@ private static void ReleaseLaunchSemaphore() } } + private static bool ShouldHideConsole(string[] args) + { + if (args.Length == 0) + { + // No verb defaults to 'ui' + return true; + } + + // --debug or -p/--preview flags keep the console visible for troubleshooting + if (args.Any(a => string.Equals(a, "--debug", StringComparison.OrdinalIgnoreCase) || + string.Equals(a, "--preview", StringComparison.OrdinalIgnoreCase) || + string.Equals(a, "-p", StringComparison.OrdinalIgnoreCase))) + { + return false; + } + + // Don't hide the console when the user explicitly requests help/version output. + if (args.Any(a => + string.Equals(a, "--help", StringComparison.OrdinalIgnoreCase) || + string.Equals(a, "-h", StringComparison.OrdinalIgnoreCase) || + string.Equals(a, "--version", StringComparison.OrdinalIgnoreCase) || + string.Equals(a, "-v", StringComparison.OrdinalIgnoreCase))) + { + return false; + } + + return string.Equals(args[0], "launch", StringComparison.OrdinalIgnoreCase) || + string.Equals(args[0], "ui", StringComparison.OrdinalIgnoreCase); + } + private static void HandleUnexpectedError(Exception ex) { Serilog.Log.Error($"Unexpected error: {ex.Message}", ex); @@ -186,7 +243,7 @@ private static void ConfigureLogging() config.MinimumLevel.ControlledBy(new Serilog.Core.LoggingLevelSwitch(ConfigurationManager.MinLogLevel.Value)); } - if (ConfigurationManager.LogToConsole) + if (!consoleHidden && ConfigurationManager.LogToConsole) { config.WriteTo.Console(); } diff --git a/src/Ui/Options.cs b/src/Ui/Options.cs index 7f8cd77..9bc1dc6 100644 --- a/src/Ui/Options.cs +++ b/src/Ui/Options.cs @@ -26,5 +26,7 @@ namespace OneIdentity.Scalus.Ui [Verb("ui", isDefault: true, HelpText = "Run the configuration UI")] public class Options : IVerb { + [Option("debug", Required = false, HelpText = "Keep the console window visible for troubleshooting.")] + public bool Debug { get; set; } } } diff --git a/src/UrlParser/DefaultRdpUrlParser.cs b/src/UrlParser/DefaultRdpUrlParser.cs index d847133..1fae2ae 100644 --- a/src/UrlParser/DefaultRdpUrlParser.cs +++ b/src/UrlParser/DefaultRdpUrlParser.cs @@ -292,15 +292,9 @@ private static X509Certificate2 CreateScalusSigningCert(IOsServices services) var res = services.Execute("powershell", new List { - "New-SelfSignedCertificate", - "-Subject", - "SCALUS", - "-NotAfter", - "(Get-Date).AddYears(5)", - "-KeyUsage", - "DigitalSignature", - "-CertStoreLocation", - "Cert:\\CurrentUser\\My", + "-NoProfile", + "-Command", + "Import-Module PKI; New-SelfSignedCertificate -Subject SCALUS -NotAfter (Get-Date).AddYears(5) -KeyUsage DigitalSignature -CertStoreLocation Cert:\\CurrentUser\\My", }, out output, out err); diff --git a/test/OneIdentity.Scalus.Test.csproj b/test/OneIdentity.Scalus.Test.csproj index 202c5e0..d9ae69a 100644 --- a/test/OneIdentity.Scalus.Test.csproj +++ b/test/OneIdentity.Scalus.Test.csproj @@ -4,14 +4,14 @@ - net6.0 + net8.0 false false signer.pfx false WinExe OneIdentity.Scalus.Test - linux-x64;osx-x64;win10-x64 + linux-x64;osx-x64;win-x64 true @@ -29,7 +29,7 @@ - + all