Show/Hide Console or HowTo Write to Console in a Windows Application in .NET 5.0

Thomas Gössi 1 Reputation point
2021-02-05T11:36:34.287+00:00

Hi There

I plan to make a mixed application, means, the user can start them to open a black console window or to open it with a WPF-GUI. The user can select with a start option like -console or -window.

Thus I created a WPF-application and set the options in the .csproj to:

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UserSecretsId>dotnet-WorkerService2-xxx...</UserSecretsId>
    <UseWPF>true</UseWPF>
    <OutputType>Exe</OutputType>
    <DisableWinExeOutputInference>True</DisableWinExeOutputInference>
  </PropertyGroup>

Dependion on the start option, I create a new thread with a WPF-application, that opens the WPF-GUI.
When I use the GUI, I hide the opening console window with:

using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

When I use the console, I do not hide them and do not create the WPF-application inside.
So then I can also see, that logs are put into the console as well as I can write text into the console window.

So it works fine.

But the problem is, when I start the application as a WPF-GUI, the console window pops up shortly and then disappears, as soon as the code has been executed to hide them, after the application has been started.
This is a little bit ugly !

Thus, I tried to change the application to run them as a windows application. Starting it, no console is created or opened. So I create them inside the application with the following code, when I need it:

using System.Runtime.InteropServices;
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int AllocConsole();

and then free them at the end:

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int FreeConsole();

And if the application is started within a console, I tried to get these console using:

using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

But the problem is, neither the log nor messages, that I want to write to the console, are shown in the console. Although I create one or get the one, that is opened from where I started the program, I cannot us them.

So I tried two ways to reach my goal, but none of them works satisfactory.
Do you have an idea, how I can solve this problem in one of the following ways:

  1. Run the application as a console application, but prevent, that the console pops up shortly after starting, if I don't use them. Maybe a console application can be started with a hidden console window, so that I can use the upper commands in kernel32.dll, the show them when I need. Thus logs and messages would be shown in the console.
  2. Run the application as a windows application. But how can I reach the already existing console, where I did start the program or allocate a new one, if the application was started within explorer, so that logs and messages are written to them.
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,667 questions
.NET CLI
.NET CLI
A cross-platform toolchain for developing, building, running, and publishing .NET applications.
322 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,204 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,117 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Will 81 Reputation points Microsoft Employee
    2021-04-09T06:34:31.257+00:00

    @Thomas ,

    You could use Console.Write() or Console.readline() to use your console windows.

    private void Button_Click(object sender, RoutedEventArgs e)  
            {  
                AllocConsole();  
                Console.WriteLine("Console text");  
                InteractiveConsole();  
            }  
      
            private void InteractiveConsole()   
            {  
                Console.WriteLine("Console Interactive");  
                string firststr = Console.ReadLine();  
                Console.WriteLine("output states {0}", firststr);  
      
      
            }  
      
            private void Button_Click_1(object sender, RoutedEventArgs e)  
            {  
                //Close Console  
                Console.Write("close concole");  
                FreeConsole();  
            }  
    

    If you want to run WPF application as console application, you may need custom WPF control like this:
    https://stackoverflow.com/questions/14948171/how-to-emulate-a-console-in-wpf
    If use InteropServices to apply console windows, you may need code to receive input message and handle it
    BR,

    0 comments No comments

  2. Rustamxon Rahimov 0 Reputation points
    2023-01-20T19:07:27.1533333+00:00

    how can i stop while hide console running

    0 comments No comments