Home > OS >  C# Console-Application with no console but winforms
C# Console-Application with no console but winforms

Time:05-04

We have an application that is a WinForms-Application. It accepts startup parameters and can perform certain jobs with no UI by using the command line.

Now, we also want some console-output, like for example when using application.exe /help.

The Issue we are now facing is: How to bring both worlds together in a "nice" way:

  1. When setting the Output Type to "Windows Application",all the UI stuff works fine, but Console.WriteLine() doesn't show results when used from cmd.

  2. When setting the Output Type to "Console", generally both things work, BUT: The Application (when used in UI-Mode so to say) raises a console window, that stays open until the application terminates.

Is there a way to bypass the visibility of the console-window?

In the real world, I can find applications using one of three approaches - but I don't like either of them:

  1. Leave the console window open when running in UI-Mode, who cares?

  2. Use user32.dll to hide the window (it still flashes, tho)

  3. Use Windows-Application as Output-Type and show Console-Output as "message boxes", when used from the command line.

CodePudding user response:

I've figured out a solution, thx to @Luaan s comment:

I'm now using the Output Type Windows Application (so, no console window) - but simply registering the Console with the Applications "Parent" Console.

This now behaves as expected:

  • No console is shown during normal startup.

  • When used from within an existing console window (ps / cmd) the output is printed, because that consoles are then technically the parent-console of the application.

    public class GUIConsoleWriter
    {
      [System.Runtime.InteropServices.DllImport("kernel32.dll")]
      private static extern bool AttachConsole(int dwProcessId);
      private const int ATTACH_PARENT_PROCESS = -1;
    
      public static void RegisterGUIConsoleWriter()
      {
          AttachConsole(ATTACH_PARENT_PROCESS);
      }
    } 
    

And then, firstline in Main():

  static void Main(String[] args)
  {
        GUIConsoleWriter.RegisterGUIConsoleWriter();
  }

Now, using regular Console.WriteLine() works. Ofc. this is limited to writing output, but for the scope of my projects that is sufficent, as input has to be provided with arguments, no interactive console-options.

When another application needs to fetch output programmatically, you ofc. can't do myApp.exe /doSomething but need to do cmd /C myApp.exe /doSomething because the application itself doesn't own a console.

AND you have to manually take care to "exit" your application, after providing output, otherwhise the process won't return.

  • Related