0

I have already read this similar quesiton but the solution accepted in that question is not working for me.

I have a WinForm application (called FormPlusConsoleApp) that works as a console application if some arguments are passed by the calling program.

I need to provide status messages from the program FormPlusConsoleApp to the console therefore, I attach to the console at the very beginning of the program.

PROBLEM: After executing the required job, the program should exit with an exit code 0/1 and should completely detach to the console without any user interaction.

I am already calling the FreeConsole() method as suggested in this similar quesiton but at the end, a blinking cursor appears on the command prompt (as shown in the screenshot) and the user must press a button to completely exit.

enter image description here

Sample Working Program:

using System;
using System.Windows.Forms;
using System.IO;

namespace FormPlusConsoleApp
{
    static class Program
    {       
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            System.Windows.Forms.MessageBox.Show("Attach the debugger now...");
            if (args.Length == 0) //form version
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FormApp());
            }
            else //start console version 
            {
                // case args.Length > 0
                SampleConsoleExecution();
            }
        }

        static void SampleConsoleExecution()
        {
            //attach to the console
            bool isAttached = AttachConsole(-1);

            //Sample Message
            Console.WriteLine(Environment.NewLine + "Console process started...");

            //do something
            Console.WriteLine(Environment.NewLine + "Exit process!");

            //Free console
            FreeConsole(); //<<<<<<<<<--------blinking cursor appears on the console but the user still have to press the "ENTER" button             
        }

        //To attach to the console (parent)
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool AttachConsole(int dwProcessId);

        //To free from the attached console
        [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeConsole();
    }
}

PS: I understand that the best approach is to have separate WinForm and console applications that use the same business logic. Unfortunately, that's not an option for me. The above code is just MWE to test the problem.

user2756695
  • 676
  • 1
  • 7
  • 22
  • Everything is normal, the output of cmd.exe and your program get arbitrarily intermingled. Cmd.exe got first, that's common, it displayed the command prompt before your program output got a chance. It has no reason to display it again unless you press the Enter key. It gets a lot worse if your program reads from the console. You'll have to start your app with `start /wait yourapp.exe` to tell cmd.exe to wait. Otherwise a good demonstration why AttachConsole() is such a bad idea. – Hans Passant Jun 11 '21 at 16:22

1 Answers1

0

As written in this blog post by Raymond Chen and this answer you can't have an app that is both, console and windows app.

There are few workarounds, the approach that worked for me is to add the following code at the end of the main function:

SendKeys.SendWait("{ENTER}");

In order to set the exit code, you could use Environment.Exit:

Environment.Exit(0);
EylM
  • 5,967
  • 2
  • 16
  • 28
  • Thanks, it resolves the issue of returning to the control to console window but as mentioned in the original post, I also need to provide the exit code. How can I send Exit Code 1 on successfully completing the program? – user2756695 Jun 14 '21 at 08:26