4

I have an working WPF application which I wanted to eqip with some console functionalities to enable batch processing. To do so, I deleted StartupUri="MainWindow.xaml" from my App.xaml, and added instead a programatic call based on command line arguments, calling either the WPF or the console application. This is working fine, just with one problem, the first Console.WriteLine() in the console application also puts out the binary path in command line.

Is there anything I also have to change?

App.xaml.cs:

using System;
using System.Linq;
using System.Windows;
using System.Windows.Forms;

namespace AppNamespace
{
    public partial class App : System.Windows.Application
    {
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool AllocConsole();
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool FreeConsole();
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool AttachConsole(int pid);

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            if (e.Args.Contains("/c"))
            {
                // try to attach to an parent process console
                if (!AttachConsole(-1))
                {
                    // Alloc a new console
                    AllocConsole();
                }

                Console.WriteLine("Line 1");
                Console.WriteLine("Line 2");

                // get command prompt back
                SendKeys.SendWait("{ENTER}");

                // detach console
                FreeConsole();
            }
            else
            {
                new MainWindow().ShowDialog();
            }
            this.Shutdown();
        }
    }
}

App.xaml:

<Application x:Class="AppNamespace.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Application.Resources>

    </Application.Resources>
</Application>

Command line output:

C:\TestProject\bin\Debug>testapp.exe /c

C:\TestProject\bin\Debug>Line 1
Line 2

C:\TestProject\bin\Debug>

Command line output wanted from me:

C:\TestProject\bin\Debug>testapp.exe /c

Line 1
Line 2

C:\TestProject\bin\Debug>
xcdark
  • 43
  • 4
  • is this the case where you already started the exe from command line or powershell (attach), or just when the application opens its own console? i have observed a similar behavior from Windows 8.1 onwards, where I could also interact with the console (type commands) while the program is still generating output. – Cee McSharpface Oct 21 '16 at 07:57

2 Answers2

2

You can achieve this behavior in the console if you change the Output type of your application from Windows Application to Console Application in the project properties.

The drawback is that you get a new console window if you start the WPF application directly. You can hide this console window with a Win32 call mentioned here but it still pops up very briefly.

As a benefit you don't have to attach to a console using AttachConsole/AllocConsole/FreeConsole anymore because you already are in a console. You can also get rid of the SendKeys.SendWait("{ENTER}"); if you replace this.Shutdown(); with Environment.Exit(0);.

Community
  • 1
  • 1
haindl
  • 3,111
  • 2
  • 25
  • 31
0

This is because your application is a Windows application, not a real Console application. When you start a Windows application from the console, it doesn't wait for the application to exit, so it just displays the prompt again in the console. I don't think it's possible to have an app that is both a Console and Windows application.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758