diff --git a/Issue1167/.runsettings b/Issue1167/.runsettings
new file mode 100644
index 0000000..d1187e1
--- /dev/null
+++ b/Issue1167/.runsettings
@@ -0,0 +1,16 @@
+
+
+
+
+ 1
+ 0
+ false
+
+
+
+
+
+
+
+
+
diff --git a/Issue1167/ConsoleRecorder.PoC/ConsoleOutput.cs b/Issue1167/ConsoleRecorder.PoC/ConsoleOutput.cs
new file mode 100644
index 0000000..db749c0
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/ConsoleOutput.cs
@@ -0,0 +1,99 @@
+using ConsoleRecorder.PoC.Utilities;
+
+namespace ConsoleRecorder.PoC.Environment
+{
+ ///
+ /// Provides services for interacting with the console output from the test host.
+ /// This class cannot be inherited.
+ ///
+ internal static class ConsoleOutput
+ {
+ ///
+ /// Gets a value indicating whether console output from the test host is enabled.
+ ///
+ public static bool IsEnabled { get; private set; }
+
+ ///
+ /// Returns a reader for the recorded standard output stream.
+ ///
+ public static TextReader Out => new StringReader(
+ _recorder.GetRecording(ConsoleRecorder.ChannelSelection.Out));
+
+ ///
+ /// Returns a reader for the recorded standard error stream.
+ ///
+ public static TextReader Error => new StringReader(
+ _recorder.GetRecording(ConsoleRecorder.ChannelSelection.Error));
+
+ ///
+ /// Returns a reader for the recorded console output.
+ ///
+ public static TextReader All => new StringReader(
+ _recorder.GetRecording(
+ ConsoleRecorder.ChannelSelection.Out | ConsoleRecorder.ChannelSelection.Error));
+
+ ///
+ /// Gets the interface to the console recorder.
+ ///
+ public static IRecorder Recorder => _recorder;
+
+ ///
+ /// A recorder for capturing console output.
+ ///
+ private static readonly ConsoleRecorder _recorder;
+
+ ///
+ /// The original standard output stream of the test host.
+ ///
+ private static readonly TextWriter _testHostStdOut;
+
+ ///
+ /// The original standard error stream of the test host.
+ ///
+ private static readonly TextWriter _testHostStdErr;
+
+ ///
+ /// Initializes static members of the class.
+ ///
+ static ConsoleOutput()
+ {
+ _recorder = new ConsoleRecorder();
+
+ _testHostStdOut = Console.Out;
+ _testHostStdErr = Console.Error;
+
+ // Intercept the console output and split it between console and recorder.
+ Console.SetOut(new DualWriter(_testHostStdOut, _recorder.Channels.Out));
+ Console.SetError(new DualWriter(_testHostStdErr, _recorder.Channels.Error));
+ IsEnabled = true;
+ }
+
+ ///
+ /// Enables console output from the test host.
+ ///
+ public static void Enable()
+ {
+ if (IsEnabled)
+ return;
+
+ Console.SetOut(new DualWriter(_testHostStdOut, _recorder.Channels.Out));
+ Console.SetError(new DualWriter(_testHostStdErr, _recorder.Channels.Error));
+
+ IsEnabled = true;
+ }
+
+ ///
+ /// Disables console output from the test host.
+ ///
+ public static void Disable()
+ {
+ if (!IsEnabled)
+ return;
+
+ Console.SetOut(new DualWriter(TextWriter.Null, _recorder.Channels.Out));
+ Console.SetError(new DualWriter(TextWriter.Null, _recorder.Channels.Error));
+
+ IsEnabled = false;
+ }
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.PoC.csproj b/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.PoC.csproj
new file mode 100644
index 0000000..f693d66
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.PoC.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.cs b/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.cs
new file mode 100644
index 0000000..b8979a8
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/ConsoleRecorder.cs
@@ -0,0 +1,125 @@
+namespace ConsoleRecorder.PoC
+{
+ using global::ConsoleRecorder.PoC.Utilities;
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Runtime.CompilerServices;
+ using System.Text;
+
+ ///
+ /// Provides recording capabilities for console output.
+ ///
+ public class ConsoleRecorder : IRecorder
+ {
+ ///
+ /// Selects the recorded channels.
+ ///
+ [Flags]
+ public enum ChannelSelection
+ {
+ ///
+ /// The recording of the standard output channel.
+ ///
+ Out = 0x1,
+
+ ///
+ /// The recording of the standard error channel.
+ ///
+ Error = 0x2
+ }
+
+ ///
+ /// Gets a value indicating whether a recording is running.
+ ///
+ public bool IsRecording { get; private set; }
+
+ internal RecorderChannels Channels { get; private set; }
+
+ ///
+ /// The list of recordings.
+ ///
+ ///
+ /// Retains individual recordings for each channel plus one combined recording.
+ ///
+ private readonly StringWriter[] _recordings;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ConsoleRecorder()
+ {
+ _recordings = Enumerable.Range(0, 3).Select(sw => new StringWriter()).ToArray();
+
+ var outRecordWriter = new RecordWriter(
+ recorder: this, record: new DualWriter(_recordings[0], _recordings[2]));
+ var errorRecordWriter = new RecordWriter(
+ recorder: this, record: new DualWriter(_recordings[1], _recordings[2]));
+
+ Channels = new RecorderChannels()
+ {
+ Out = outRecordWriter,
+ Error = errorRecordWriter
+ };
+
+ IsRecording = false;
+ }
+
+ ///
+ public void Start()
+ {
+ if (IsRecording)
+ {
+ throw new InvalidOperationException(
+ "Cannot start recording. A recording is already in progress. " +
+ "Stop the current recording before starting a new one.");
+ }
+
+ IsRecording = true;
+ }
+
+ ///
+ public void Stop()
+ {
+ if (!IsRecording)
+ {
+ throw new InvalidOperationException(
+ "Cannot stop recording. No recording is currently in progress. " +
+ "Start a recording before attempting to stop it.");
+ }
+
+ IsRecording = false;
+ }
+
+ ///
+ public void Reset()
+ {
+ if (IsRecording)
+ {
+ throw new InvalidOperationException(
+ "Cannot reset the recorder while a recording is in progress. " +
+ "Stop the current recording before resetting.");
+ }
+
+ foreach (var recording in _recordings)
+ recording.GetStringBuilder().Clear();
+ }
+
+ ///
+ /// Returns the recorded console output.
+ ///
+ /// The type of recording.
+ /// A string containing the recorded console output.
+ public string GetRecording(ChannelSelection channels)
+ {
+ if (channels.HasFlag(ChannelSelection.Out) && channels.HasFlag(ChannelSelection.Error))
+ return _recordings[2].ToString();
+ else if (channels.HasFlag(ChannelSelection.Out))
+ return _recordings[0].ToString();
+ else if (channels.HasFlag(ChannelSelection.Error))
+ return _recordings[1].ToString();
+ else
+ return string.Empty;
+ }
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/DualWriter.cs b/Issue1167/ConsoleRecorder.PoC/DualWriter.cs
new file mode 100644
index 0000000..cf852d1
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/DualWriter.cs
@@ -0,0 +1,78 @@
+using System.Text;
+
+namespace ConsoleRecorder.PoC.Utilities
+{
+ ///
+ /// Implements a for writing text to two writers in turn.
+ ///
+ ///
+ /// This writer does not implement a backing store.
+ ///
+ internal class DualWriter : TextWriter
+ {
+ private readonly TextWriter _primaryWriter;
+ private readonly TextWriter _secondaryWriter;
+
+ ///
+ public override Encoding Encoding => Encoding.Default;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The primary writer to write a copy to.
+ /// The secondary writer to write a copy to.
+ /// Thrown if any of the arguments is null.
+ public DualWriter(TextWriter primaryWriter, TextWriter secondaryWriter)
+ {
+ ArgumentNullException.ThrowIfNull(primaryWriter);
+ ArgumentNullException.ThrowIfNull(secondaryWriter);
+
+ _primaryWriter = primaryWriter;
+ _secondaryWriter = secondaryWriter;
+ }
+
+ ///
+ public override void Write(char value)
+ {
+ _primaryWriter.Write(value);
+ _secondaryWriter.Write(value);
+ }
+
+ ///
+ ///
+ /// This override exists as a workaround for the erroneous writing
+ /// of single characters to the standard error stream when using NUnit.
+ /// For more information, refer to issue #4414.
+ ///
+ public override void Write(string? value)
+ {
+ if (value is not null)
+ {
+ _primaryWriter.Write(value);
+ _secondaryWriter.Write(value);
+ }
+ }
+
+ ///
+ ///
+ /// This override exists as a workaround for the erroneous writing
+ /// of single characters to the standard error stream when using NUnit.
+ /// For more information, refer to issue #4414.
+ ///
+ public override void WriteLine(string? value)
+ {
+ if (value is not null)
+ {
+ _primaryWriter.WriteLine(value);
+ _secondaryWriter.WriteLine(value);
+ }
+ }
+
+ ///
+ public override void Flush()
+ {
+ _primaryWriter.Flush();
+ _secondaryWriter.Flush();
+ }
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/IRecorder.cs b/Issue1167/ConsoleRecorder.PoC/IRecorder.cs
new file mode 100644
index 0000000..79275ec
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/IRecorder.cs
@@ -0,0 +1,28 @@
+namespace ConsoleRecorder.PoC
+{
+ ///
+ /// Provides mechanisms for recording data.
+ ///
+ public interface IRecorder
+ {
+ ///
+ /// Gets a value indicating whether a recording is running.
+ ///
+ bool IsRecording { get; }
+
+ ///
+ /// Starts the recording.
+ ///
+ void Start();
+
+ ///
+ /// Stops the recording.
+ ///
+ void Stop();
+
+ ///
+ /// Erases the recorded data and prepares the recorder for a new recording.
+ ///
+ void Reset();
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/RecordWriter.cs b/Issue1167/ConsoleRecorder.PoC/RecordWriter.cs
new file mode 100644
index 0000000..378fc1c
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/RecordWriter.cs
@@ -0,0 +1,46 @@
+using System.Text;
+
+namespace ConsoleRecorder.PoC
+{
+ ///
+ /// Implements a that records data for an .
+ ///
+ /// This writer does not implement a backing store.
+ internal class RecordWriter : TextWriter
+ {
+ ///
+ /// The recorder that controls the recording.
+ ///
+ private readonly IRecorder _recorder;
+
+ ///
+ /// The record to which data is written.
+ ///
+ private readonly TextWriter _record;
+
+ ///
+ public override Encoding Encoding => _record.Encoding;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The recorder that controls the recording.
+ /// The record to which data is written.
+ /// Thrown if any of the arguments is null.
+ public RecordWriter(IRecorder recorder, TextWriter record)
+ {
+ ArgumentNullException.ThrowIfNull(recorder);
+ _recorder = recorder;
+
+ ArgumentNullException.ThrowIfNull(record);
+ _record = record;
+ }
+
+ ///
+ public override void Write(char value)
+ {
+ if (_recorder.IsRecording)
+ _record.Write(value);
+ }
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/RecorderChannels.cs b/Issue1167/ConsoleRecorder.PoC/RecorderChannels.cs
new file mode 100644
index 0000000..dfcf99a
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/RecorderChannels.cs
@@ -0,0 +1,11 @@
+namespace ConsoleRecorder.PoC
+{
+ ///
+ /// Represents the channel set of a .
+ ///
+ internal struct RecorderChannels
+ {
+ public TextWriter Out;
+ public TextWriter Error;
+ }
+}
diff --git a/Issue1167/ConsoleRecorder.PoC/SystemTests.cs b/Issue1167/ConsoleRecorder.PoC/SystemTests.cs
new file mode 100644
index 0000000..abc4a28
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/SystemTests.cs
@@ -0,0 +1,56 @@
+using ConsoleRecorder.PoC.Environment;
+using NUnit.Framework.Constraints;
+
+namespace ConsoleRecorder.PoC
+{
+ public class SystemTests
+ {
+ [TestCase(TestName = "Warning is output if called with multiple arguments")]
+ public void Program_MultipleArguments_OutputsWarning()
+ {
+ const string ignoredArgsWarning = "Ignoring excess arguments";
+
+ ConsoleOutput.Recorder.Start();
+ Program.Main(new string[] { "John", "42" });
+ ConsoleOutput.Recorder.Stop();
+
+ string errorOutput = ConsoleOutput.Error.ReadToEnd();
+ Assert.That(errorOutput, Contains.Substring(ignoredArgsWarning));
+
+ ConsoleOutput.Recorder.Reset();
+ }
+
+ [TestCase(TestName = "Warning is output before greeting if called with multiple arguments")]
+ public void Program_MultipleArguments_WarningBeforeGreeting()
+ {
+ const string warning = "Warning:";
+ const string greeting = "Hello";
+
+ ConsoleOutput.Recorder.Start();
+ Program.Main(new string[] { "John", "42" });
+ ConsoleOutput.Recorder.Stop();
+
+ var output = ConsoleOutput.All;
+ string? line = output.ReadLine();
+ Assert.That(line, Is.Not.Null);
+ Assert.That(line!.StartsWith(warning));
+ line = output.ReadLine();
+ Assert.That(line, Is.Not.Null);
+ Assert.That(line!.Contains(greeting));
+
+ ConsoleOutput.Recorder.Reset();
+ }
+
+ [TestCase(TestName = "Test case with suppressed console output")]
+ public void Program_NoConsoleOutput()
+ {
+ ConsoleOutput.Disable();
+ Console.Out.WriteLine("This output will be suppressed!");
+ Console.Error.WriteLine("And so will be this!");
+ ConsoleOutput.Enable();
+
+ Program.Main(new string[] { "John", "42" });
+ Assert.Pass();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Issue1167/ConsoleRecorder.PoC/Usings.cs b/Issue1167/ConsoleRecorder.PoC/Usings.cs
new file mode 100644
index 0000000..7453056
--- /dev/null
+++ b/Issue1167/ConsoleRecorder.PoC/Usings.cs
@@ -0,0 +1,2 @@
+global using MyApp;
+global using NUnit.Framework;
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.MSTest/MyApp.Tests.MSTest.csproj b/Issue1167/MyApp.Tests.MSTest/MyApp.Tests.MSTest.csproj
new file mode 100644
index 0000000..1d75267
--- /dev/null
+++ b/Issue1167/MyApp.Tests.MSTest/MyApp.Tests.MSTest.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Issue1167/MyApp.Tests.MSTest/UnitTests.cs b/Issue1167/MyApp.Tests.MSTest/UnitTests.cs
new file mode 100644
index 0000000..9c91be2
--- /dev/null
+++ b/Issue1167/MyApp.Tests.MSTest/UnitTests.cs
@@ -0,0 +1,29 @@
+using Microsoft.VisualStudio.TestPlatform.TestHost;
+
+namespace MyApp.Tests.MSTest
+{
+ [TestClass]
+ public class UnitTests
+ {
+ [TestMethod("Main method returns zero exit code if called with single argument")]
+ public void Main_SingleArgument_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John" });
+ Assert.AreEqual(exitCode, 0);
+ }
+
+ [TestMethod("Main method returns non-zero exit code if called with no arguments")]
+ public void Main_NoArguments_ReturnsNonZeroExitCode()
+ {
+ int exitCode = Program.Main(Array.Empty());
+ Assert.AreNotEqual(exitCode, 0);
+ }
+
+ [TestMethod("Main method returns zero exit code if called with multiple arguments")]
+ public void Main_MultipleArguments_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John", "42" });
+ Assert.AreEqual(exitCode, 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.MSTest/Usings.cs b/Issue1167/MyApp.Tests.MSTest/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Issue1167/MyApp.Tests.MSTest/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.NUnit/MyApp.Tests.NUnit.csproj b/Issue1167/MyApp.Tests.NUnit/MyApp.Tests.NUnit.csproj
new file mode 100644
index 0000000..f693d66
--- /dev/null
+++ b/Issue1167/MyApp.Tests.NUnit/MyApp.Tests.NUnit.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Issue1167/MyApp.Tests.NUnit/UnitTests.cs b/Issue1167/MyApp.Tests.NUnit/UnitTests.cs
new file mode 100644
index 0000000..3714ea6
--- /dev/null
+++ b/Issue1167/MyApp.Tests.NUnit/UnitTests.cs
@@ -0,0 +1,28 @@
+using Microsoft.VisualStudio.TestPlatform.TestHost;
+
+namespace MyApp.Tests.NUnit
+{
+ public class UnitTests
+ {
+ [TestCase(TestName = "Main method returns zero exit code if called with single argument")]
+ public void Main_SingleArgument_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John" });
+ Assert.That(exitCode, Is.EqualTo(0));
+ }
+
+ [TestCase(TestName = "Main method returns non-zero exit code if called with no arguments")]
+ public void Main_NoArguments_ReturnsNonZeroExitCode()
+ {
+ int exitCode = Program.Main(Array.Empty());
+ Assert.That(exitCode, Is.Not.EqualTo(0));
+ }
+
+ [TestCase(TestName = "Main method returns zero exit code if called with multiple arguments")]
+ public void Main_MultipleArguments_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John", "42" });
+ Assert.That(exitCode, Is.EqualTo(0));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.NUnit/Usings.cs b/Issue1167/MyApp.Tests.NUnit/Usings.cs
new file mode 100644
index 0000000..cefced4
--- /dev/null
+++ b/Issue1167/MyApp.Tests.NUnit/Usings.cs
@@ -0,0 +1 @@
+global using NUnit.Framework;
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.xUnit/MyApp.Tests.xUnit.csproj b/Issue1167/MyApp.Tests.xUnit/MyApp.Tests.xUnit.csproj
new file mode 100644
index 0000000..402aecf
--- /dev/null
+++ b/Issue1167/MyApp.Tests.xUnit/MyApp.Tests.xUnit.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/Issue1167/MyApp.Tests.xUnit/UnitTests.cs b/Issue1167/MyApp.Tests.xUnit/UnitTests.cs
new file mode 100644
index 0000000..5adaf18
--- /dev/null
+++ b/Issue1167/MyApp.Tests.xUnit/UnitTests.cs
@@ -0,0 +1,28 @@
+using Microsoft.VisualStudio.TestPlatform.TestHost;
+
+namespace MyApp.Tests.xUnit
+{
+ public class UnitTests
+ {
+ [Fact(DisplayName = "Main method returns zero exit code if called with single argument")]
+ public void Main_SingleArgument_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John" });
+ Assert.Equal(0, exitCode);
+ }
+
+ [Fact(DisplayName = "Main method returns non-zero exit code if called with no arguments")]
+ public void Main_NoArguments_ReturnsNonZeroExitCode()
+ {
+ int exitCode = Program.Main(Array.Empty());
+ Assert.NotEqual(0, exitCode);
+ }
+
+ [Fact(DisplayName = "Main method returns zero exit code if called with multiple arguments")]
+ public void Main_MultipleArguments_ReturnsZeroExitCode()
+ {
+ int exitCode = Program.Main(new string[] { "John", "42" });
+ Assert.Equal(0, exitCode);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Issue1167/MyApp.Tests.xUnit/Usings.cs b/Issue1167/MyApp.Tests.xUnit/Usings.cs
new file mode 100644
index 0000000..8c927eb
--- /dev/null
+++ b/Issue1167/MyApp.Tests.xUnit/Usings.cs
@@ -0,0 +1 @@
+global using Xunit;
\ No newline at end of file
diff --git a/Issue1167/MyApp.sln b/Issue1167/MyApp.sln
new file mode 100644
index 0000000..f09d50f
--- /dev/null
+++ b/Issue1167/MyApp.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp", "MyApp\MyApp.csproj", "{EE6C42F3-BFD6-45B4-9D50-7F0065388F9C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.Tests.NUnit", "MyApp.Tests.NUnit\MyApp.Tests.NUnit.csproj", "{8BD72ECF-5E52-4504-AA76-47D9572F87C6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.Tests.MSTest", "MyApp.Tests.MSTest\MyApp.Tests.MSTest.csproj", "{92C4947C-FB98-4B2A-9752-6998A64C7214}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyApp.Tests.xUnit", "MyApp.Tests.xUnit\MyApp.Tests.xUnit.csproj", "{9C36E3E8-62D1-4ED8-BC06-7AEE6C81EAEB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleRecorder.PoC", "ConsoleRecorder.PoC\ConsoleRecorder.PoC.csproj", "{7581E09A-13AC-49D0-B80B-661A67EBF86A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EE6C42F3-BFD6-45B4-9D50-7F0065388F9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EE6C42F3-BFD6-45B4-9D50-7F0065388F9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EE6C42F3-BFD6-45B4-9D50-7F0065388F9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EE6C42F3-BFD6-45B4-9D50-7F0065388F9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8BD72ECF-5E52-4504-AA76-47D9572F87C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8BD72ECF-5E52-4504-AA76-47D9572F87C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8BD72ECF-5E52-4504-AA76-47D9572F87C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8BD72ECF-5E52-4504-AA76-47D9572F87C6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92C4947C-FB98-4B2A-9752-6998A64C7214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92C4947C-FB98-4B2A-9752-6998A64C7214}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92C4947C-FB98-4B2A-9752-6998A64C7214}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92C4947C-FB98-4B2A-9752-6998A64C7214}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C36E3E8-62D1-4ED8-BC06-7AEE6C81EAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C36E3E8-62D1-4ED8-BC06-7AEE6C81EAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C36E3E8-62D1-4ED8-BC06-7AEE6C81EAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C36E3E8-62D1-4ED8-BC06-7AEE6C81EAEB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7581E09A-13AC-49D0-B80B-661A67EBF86A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7581E09A-13AC-49D0-B80B-661A67EBF86A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7581E09A-13AC-49D0-B80B-661A67EBF86A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7581E09A-13AC-49D0-B80B-661A67EBF86A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0A0C85E3-CFEA-42A8-A371-87FE41380154}
+ EndGlobalSection
+EndGlobal
diff --git a/Issue1167/MyApp/MyApp.csproj b/Issue1167/MyApp/MyApp.csproj
new file mode 100644
index 0000000..a964a26
--- /dev/null
+++ b/Issue1167/MyApp/MyApp.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/Issue1167/MyApp/Program.cs b/Issue1167/MyApp/Program.cs
new file mode 100644
index 0000000..eba80e3
--- /dev/null
+++ b/Issue1167/MyApp/Program.cs
@@ -0,0 +1,24 @@
+namespace MyApp
+{
+ internal class Program
+ {
+ const int ExitCodeSuccess = 0;
+ const int ExitCodeFailure = 1;
+
+ internal static int Main(string[] args)
+ {
+ if (args.Length == 0)
+ {
+ Console.Error.WriteLine("Error: No user name provided.");
+ return ExitCodeFailure;
+ }
+ else if (args.Length > 1)
+ Console.Error.WriteLine("Warning: Ignoring excess arguments.");
+
+ string userName = args[0];
+ Console.WriteLine("Hello, {0}!", userName);
+
+ return ExitCodeSuccess;
+ }
+ }
+}
\ No newline at end of file