Search code examples
c#.net-corevisual-studio-2019.net-5

C# program exits immediately if UseWPF/UseWindowsForms set to true


The program:

Public Class QueryExecutor
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter y");
        if (Console.ReadLine() == "y") return;
    }
}

The old .csproj. This causes the program to correctly ask for input in a console window.

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

The new .csproj. This causes the program to exit without opening a console.

<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
    <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

The output from the new .csproj:

'TFSHygiene.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.9\System.Private.CoreLib.dll'. 
'TFSHygiene.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Nathan_Dehnel\source\repos\TFSHygiene\bin\Debug\net5.0-windows\TFSHygiene.dll'. Symbols loaded.
'TFSHygiene.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.9\System.Runtime.dll'. 
'TFSHygiene.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.9\System.Console.dll'. 
'TFSHygiene.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.9\System.Threading.dll'. 
'TFSHygiene.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.9\System.Text.Encoding.Extensions.dll'. 
The program '[31740] TFSHygiene.exe' has exited with code 0 (0x0).

Solution

  • Breaking change in .NET 5.

    MS Docs:

    OutputType is automatically set to WinExe for Windows Presentation Foundation (WPF) and Windows Forms apps. When OutputType is set to WinExe, a console window doesn't open when the app is executed.

    (...)

    Recommended action

    No action is required in your part. However, if you want to revert to the old behavior, set the DisableWinExeOutputInference property to true in your project file.

    <DisableWinExeOutputInference>true</DisableWinExeOutputInference>
    

    Your app is quitting because there is no standard input to use ReadLine() on.