2

I want to change a WinForms application that way, so it will run without UI with console output if it is called with a command line argument. Therefore I changed the application type to "Console Application" and wrote something like:

my code snippet:
    ....
    [DllImport("kernel32.dll")]
    static extern bool FreeConsole();

    [STAThread]
    static void Main(string[] args)
    {            
        if (args.Length == 0)
        {
            FreeConsole();
            Application.Run(new MyForm());  
        }          
        else 
            Console.WriteLine("Console party");
    .....

In debug mode in VS I can see the DOS box popping up and hiding. If I do so via console, the command line keeps attached to the process and is not responding until I've closed the MyForm window. Calling the application with an argument, brings the "Console party" up.

The return value of FreeConsole is true and GetLastError is not telling any error code.

Does anybody knows how to detach the process from the cmd.exe process?

Albi
  • 310
  • 2
  • 13
  • 1
    This is a question that has been asked over and over again. The only reliable way to do this is to have two versions of your process. Versions that target GUI and console subsystems. See python.exe and pythonw.exe or java.exe and javaw.exe for canonical examples. – David Heffernan Aug 13 '14 at 12:31

1 Answers1

1

Brainstorming with a colleague brings me to try another way. I've set the application type back to Windows Application and did the following:

    ...

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int input);
    static void Main(string[] args)
    {            
        if (args.Length == 0)
        {   
            Application.Run(new MyForm());
        }
        else if (args.Length == 1)
        {
            AttachConsole(-1);
            Console.WriteLine("Console party");
    ...

What happens now is, if I run it from cmd.exe box, the application takes the console(stdin,stdou,stderr) from the parent process and writes to it. When using it without arguments, the console window will not pop up.

I am thinking about, what is better way. Having the parent process dealing with the stdin,stdout and stderr handles or let the application hijack it from its parent!?

Albi
  • 310
  • 2
  • 13
  • 1
    What happens when the parent process closes, and you've attached to its console, is that your process is closed too. Not always what you want. What's more, because your process is GUI subsystem, then when you start it from cmd, cmd knows it is a GUI process and does what usually happens in that scenario which is to start it, and then continue expecting to receive input. So, which of the two processes is going to handle the input on stdin? Bottom line here is that you have to decide at compile time whether your program is GUI or console. – David Heffernan Aug 13 '14 at 12:34
  • Thats what I think about, too. In the GUI process way it explains, why the console is not released. Searching around I found, that was possible until Win98 but makes more sense with the current behavior. – Albi Aug 13 '14 at 12:40
  • Do it as I said in my comment to the question. Two executables, one GUI, one console. – David Heffernan Aug 13 '14 at 12:41
  • That is what I want to work around. But if there's no better way, I'll do so. – Albi Aug 13 '14 at 12:52
  • 1
    You'll find countless questions here on SO trying to do what you are doing, but the answer is always the same! – David Heffernan Aug 13 '14 at 12:53
  • 1
    Of course, it's not that important for my life if I have two executables or not. For me it is interesting what happens behind. Thanks for your help. – Albi Aug 13 '14 at 13:02
  • 1
    http://stackoverflow.com/a/494000/288393 - rob kennedy explains quite eloquently what the options are - bottom line, either accept a flash of a console window, or have two executables (one for ui, one for console). – Tahir Hassan Feb 26 '16 at 12:20