Как открыть консоль windows forms

This worked for me, to pipe the output to a file.
Call the console with

cmd /c «C:\path\to\your\application.exe» > myfile.txt

Add this code to your application.

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool GetFileInformationByHandle(
        SafeFileHandle hFile,
        out BY_HANDLE_FILE_INFORMATION lpFileInformation
        );
    [DllImport("kernel32.dll")]
    private static extern SafeFileHandle GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(UInt32 nStdHandle, SafeFileHandle hHandle);
    [DllImport("kernel32.dll")]
    private static extern bool DuplicateHandle(
        IntPtr hSourceProcessHandle,
        SafeFileHandle hSourceHandle,
        IntPtr hTargetProcessHandle,
        out SafeFileHandle lpTargetHandle,
        UInt32 dwDesiredAccess,
        Boolean bInheritHandle,
        UInt32 dwOptions
        );
    private const UInt32 ATTACH_PARENT_PROCESS = 0xFFFFFFFF;
    private const UInt32 STD_OUTPUT_HANDLE = 0xFFFFFFF5;
    private const UInt32 STD_ERROR_HANDLE = 0xFFFFFFF4;
    private const UInt32 DUPLICATE_SAME_ACCESS = 2;
    struct BY_HANDLE_FILE_INFORMATION
    {
        public UInt32 FileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
        public UInt32 VolumeSerialNumber;
        public UInt32 FileSizeHigh;
        public UInt32 FileSizeLow;
        public UInt32 NumberOfLinks;
        public UInt32 FileIndexHigh;
        public UInt32 FileIndexLow;
    }
    static void InitConsoleHandles()
    {
        SafeFileHandle hStdOut, hStdErr, hStdOutDup, hStdErrDup;
        BY_HANDLE_FILE_INFORMATION bhfi;
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        hStdErr = GetStdHandle(STD_ERROR_HANDLE);
        // Get current process handle
        IntPtr hProcess = Process.GetCurrentProcess().Handle;
        // Duplicate Stdout handle to save initial value
        DuplicateHandle(hProcess, hStdOut, hProcess, out hStdOutDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Duplicate Stderr handle to save initial value
        DuplicateHandle(hProcess, hStdErr, hProcess, out hStdErrDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Attach to console window – this may modify the standard handles
        AttachConsole(ATTACH_PARENT_PROCESS);
        // Adjust the standard handles
        if (GetFileInformationByHandle(GetStdHandle(STD_OUTPUT_HANDLE), out bhfi))
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOutDup);
        }
        else
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOut);
        }
        if (GetFileInformationByHandle(GetStdHandle(STD_ERROR_HANDLE), out bhfi))
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErrDup);
        }
        else
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErr);
        }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // initialize console handles
        InitConsoleHandles();

        if (args.Length != 0)
        {

            if (args[0].Equals("waitfordebugger"))
            {
                MessageBox.Show("Attach the debugger now");
            }
            if (args[0].Equals("version"))
            {
#if DEBUG
                String typeOfBuild = "d";
#else
                String typeOfBuild = "r";
#endif
                String output = typeOfBuild + Assembly.GetExecutingAssembly()
                    .GetName().Version.ToString();
                //Just for the fun of it
                Console.Write(output);
                Console.Beep(4000, 100);
                Console.Beep(2000, 100);
                Console.Beep(1000, 100);
                Console.Beep(8000, 100);
                return;
            }
        }
    }

I found this code here: http://www.csharp411.com/console-output-from-winforms-application/
I thought is was worthy to post it here as well.

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

1

26.12.2010, 12:18. Показов 78929. Ответов 13


Студворк — интернет-сервис помощи студентам

Необходимо при работе win приложения вызывать консоль для ввода/вывода данных.
Реально ли это вообще сделать ?



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

26.12.2010, 12:18

13

zalogic

194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 12:28

2

конечно реально. Какую именно консоль?

если просто консольное приложение надо:

C#
1
System.Diagnostics.Process.Start(Application.StartupPath + @"\gr.exe");



1



Иван_007

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 12:36

 [ТС]

3

Цитата
Сообщение от zalogic
Посмотреть сообщение

Какую именно консоль?

Обычную консоль, как в консольном приложении.

Например ,что-бы считать данные можно было так :

C#
1
Console.ReadLine();



0



194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 12:45

4

Цитата
Сообщение от Иван_007
Посмотреть сообщение

Например ,что-бы считать данные можно было так :

как вызвать я написал, а как обеспечить синхронизацию ,сам придумай. Варианты есть разные.
Можешь через временный фаил.

Вот ещё почитай, хотя там тоже самое что я написал.
Запуск консольного приложения из WindowsForm

или ты как объект(класс объявить) хочешь в винформсе создать консль?



0



27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 12:56

 [ТС]

5

Цитата
Сообщение от zalogic
Посмотреть сообщение

или ты как объект(класс объявить) хочешь в винформсе создать консль?

Именно это и хочу .

Идея в следующем :

Есть основная форма . В определенный момент она должна открыть консоль и считать оттуда введенные данные .



0



zalogic

194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 13:12

6

хмм…

C#
1
using System.Console;

пространство для консолей. Как создать не скажу. Но куча есть обратных задач из консольного -> винформс (н-р http://theseus.blog.ru/91016531.html). Может как-то на их основе.



0



NickoTin

Почетный модератор

Эксперт .NET

8717 / 3669 / 404

Регистрация: 14.06.2010

Сообщений: 4,513

Записей в блоге: 9

26.12.2010, 14:48

7

Лучший ответ Сообщение было отмечено как решение

Решение

Иван_007, можно с помощью WinAPI:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Runtime.InteropServices;
...
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole ();
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool FreeConsole ();
...
        /* где-нибудь в кнопке, а лучше в отдельном потоке
         * т.к. во время чтения из консоли основной поток
         * приложения будет заморожен */
        if (AllocConsole()) {
            Console.WriteLine("Ввод данных");
            Console.ReadLine();
            FreeConsole();
        }

p.s. У приложения всего может быть только одно окно с консолью, так что одновременный вызов AllocConsole в нескольких местах не приведет к созданию нового окна.



12



Unril

822 / 713 / 110

Регистрация: 06.10.2010

Сообщений: 825

Записей в блоге: 1

26.12.2010, 16:18

8

Лучший ответ Сообщение было отмечено как решение

Решение

К примеру можно сделать так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApplicationTest
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            // Запускаем поток с консолью.
            Task.Factory.StartNew(Console);
        }
 
        private void Console()
        {
            // Запускаем консоль.
            if (AllocConsole())
            {
                System.Console.WriteLine("Для выхода наберите exit.");
                while (true)
                {
                    // Считываем данные.
                    string output = System.Console.ReadLine();
                    if (output == "exit")
                        break;
                    // Выводим данные в textBox
                    Action action = () => textBox.Text += output + Environment.NewLine;
                    if (InvokeRequired)
                        Invoke(action);
                    else
                        action();
                }
                // Закрываем консоль.
                FreeConsole();
            }
        }
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool AllocConsole();
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FreeConsole();
    }
}



8



27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 17:29

 [ТС]

9

Unril,
SSTREGG,

Спасибо огромное ,именно то что нужно было.



0



0 / 0 / 1

Регистрация: 08.11.2012

Сообщений: 11

26.10.2014, 22:40

10

СПАСИБО, вызов консоли в событии клика кнопки, а затем продолжение работы кода формы РАБОТАЕТ!!!



0



grupetto

0 / 0 / 0

Регистрация: 28.11.2015

Сообщений: 4

23.10.2016, 14:28

11

А где вы инфу по таким вещам берете? Имею в виду:

C#
1
2
3
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

В Шилдте или Троелсене такого вроде нет.

И вопрос — когда создается консольное приложение то тоже импортируется эта библиотека?



0



134 / 130 / 107

Регистрация: 17.03.2009

Сообщений: 364

23.10.2016, 22:23

12

Цитата
Сообщение от grupetto
Посмотреть сообщение

А где вы инфу по таким вещам берете? Имею в виду:

Ну, я, например на стеке нашел за пару секунд.



0



978 / 873 / 350

Регистрация: 26.04.2012

Сообщений: 2,647

24.10.2016, 08:26

13



0



Enflamed

3 / 3 / 1

Регистрация: 12.04.2015

Сообщений: 74

19.12.2016, 05:59

14

Цитата
Сообщение от grupetto
Посмотреть сообщение

где вы инфу по таким вещам берете? Имею в виду:

C#
1
2
3
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

Это не C#, это winapi. Поэтому в Шилдте и нету. WinApi, насколько я знаю, написаны на C++.
То есть, по сути, мы используем импорт куска кода из C++ при компиляции программы… Вообще, Вы правы, в обучающих курсах и книгах по C# часто вообще ни слова про p/invoke. Я лично считаю, что эту тему необходимо изучать ещё до того, как начал создание приложений с пользовательским интерфейсом.



0



3 Answers

All you need to do is call the windows API function AllocConsloe then use the normal console class here is the form code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace waTest
{
    public partial class Form1 : Form
    {
        [DllImport("Kernel32.dll")]
        static extern Boolean AllocConsole( );

        public Form1( )
        {
            InitializeComponent();
        }

        private void Form1_Load( object sender, EventArgs e )
        {
            if ( !AllocConsole() )
                 MessageBox.Show("Failed");
            Console.WriteLine("test");
            string input = Console.ReadLine();
            MessageBox.Show(input);
        }
    }
}

svick's user avatar

svick

237k50 gold badges385 silver badges515 bronze badges

answered Oct 12, 2010 at 17:23

rerun's user avatar

rerunrerun

25k6 gold badges48 silver badges78 bronze badges

7

  • @rerun, what is the deal, it can’t find Kernal32.dll? This is an x86 system.

    Oct 12, 2010 at 18:09

  • @rerun, must be that I had set this as a console app, not a winforms app. I assume Form1_Load is supposed to run when the form loads, is this correct? How do I get it to run?.

    Oct 12, 2010 at 18:12

  • Just create a winforms app with 1 form and double click on the form and it will create you a form_load you can however call allocconsle anywhere since only one console can be associated with a process.

    Oct 12, 2010 at 18:35

  • Oh you want the console in the window. You can write your own and pipe input to and from stdout and stdin. Or you can imbed powershell but there is no baked in control.

    Oct 12, 2010 at 19:49

  • «I would like to have a console window EMBEDDED in a Winform» — pretty clear.

    Jun 22, 2011 at 14:40

Oh! You want the console in the window. You can write your own and pipe input to and from stdout and stdin. Or you can imbed powershell but there is no baked in control. – rerun Oct 12 ’10 at 19:49

Community's user avatar

answered Jun 22, 2011 at 13:55

Arlen Beiler's user avatar

Arlen BeilerArlen Beiler

15.4k34 gold badges92 silver badges135 bronze badges

1

  • Why is this answer (the only one which actuall is a real answer) not at the top?

    May 31, 2017 at 19:16

You can do this basically by:

  1. Creating the cmd process
  2. Setting the parent of that process to be the form (or some panel for example)
  3. Plug in the events to resize when needed
  4. Kill the process when the main process doesn’t need the cmd process anymore.

You need to call the API directly for this (you need SetParent and SetWindowPos). Here is an article on how to do it with examples:

http://www.geekpedia.com/tutorial230_Capturing-Applications-in-a-Form-with-API-Calls.html

answered Oct 13, 2010 at 1:00

steinar's user avatar

steinarsteinar

9,4031 gold badge23 silver badges37 bronze badges

  • Remove From My Forums
  • Question

  • I wrote a demo program for my students comparing the procedural code in a Console app with the user-controlled event-driven GUI app.  The code for the Console app is shown inside a multi-line textbox, while a group of buttons runs similar code in separate event procedures. 

    Now I would like to add another button that will open a Console window and execute the code similar to what is shown in the text box.  The console window would need to open, run the code (with a ReadLine pause at the end) and then close.

    How would I go about doing that?

Answers

  • Hi Solitaire,

    Try the following code snippet to see whether it satisfies your requirement.

    Imports System.Runtime.InteropServices
    Public Class Form1
        Declare Function AllocConsole Lib «kernel32» () As IntPtr
        Declare Function FreeConsole Lib «kernel32» () As Integer
        Declare Function CloseHandle Lib «kernel32» (ByVal hObject As IntPtr) As Integer
        Declare Function GetStdHandle Lib «kernel32» (ByVal nStdHandle As Integer) As Integer
        <DllImport(«kernel32.dll»)> _
        Private Shared Function WriteConsole(ByVal hConsoleOutput As IntPtr, ByVal lpBuffer As String, ByVal nNumberOfCharsToWrite As UInteger, _
            ByRef lpNumberOfCharsWritten As UInteger, ByVal lpReserved As IntPtr) As Boolean
        End Function
        Public Const STD_OUTPUT_HANDLE As Short = -11
        Dim hConsole As IntPtr
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            hConsole = AllocConsole
            If hConsole.ToInt32 <> 0 Then
                Console.WriteLine(«THIS IS FIRST LINE»)
                Console.WriteLine(«THIS IS SECOND LINE»)
                Console.WriteLine(«THIS IS THIRD LINE»)
                Console.WriteLine(«THIS IS FOURTH LINE»)
                Console.WriteLine(«THIS IS FIFTH LINE»)
                Console.WriteLine(«Hit Enter to Clear»)
                Console.ReadLine()
                System.Console.Clear()
                Console.WriteLine(«THE CONSOLE WAS CLEARED»)
                Console.WriteLine(«Enter esc to Terminate»)
                Dim i As String = Console.ReadLine()
                MessageBox.Show(i)
                CloseHandle(hConsole)
                FreeConsole()
            End If
        End Sub
    End Class

    Best regards,
    Riquel

This worked for me, to pipe the output to a file.
Call the console with

cmd /c «C:pathtoyourapplication.exe» > myfile.txt

Add this code to your application.

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool GetFileInformationByHandle(
        SafeFileHandle hFile,
        out BY_HANDLE_FILE_INFORMATION lpFileInformation
        );
    [DllImport("kernel32.dll")]
    private static extern SafeFileHandle GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(UInt32 nStdHandle, SafeFileHandle hHandle);
    [DllImport("kernel32.dll")]
    private static extern bool DuplicateHandle(
        IntPtr hSourceProcessHandle,
        SafeFileHandle hSourceHandle,
        IntPtr hTargetProcessHandle,
        out SafeFileHandle lpTargetHandle,
        UInt32 dwDesiredAccess,
        Boolean bInheritHandle,
        UInt32 dwOptions
        );
    private const UInt32 ATTACH_PARENT_PROCESS = 0xFFFFFFFF;
    private const UInt32 STD_OUTPUT_HANDLE = 0xFFFFFFF5;
    private const UInt32 STD_ERROR_HANDLE = 0xFFFFFFF4;
    private const UInt32 DUPLICATE_SAME_ACCESS = 2;
    struct BY_HANDLE_FILE_INFORMATION
    {
        public UInt32 FileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
        public UInt32 VolumeSerialNumber;
        public UInt32 FileSizeHigh;
        public UInt32 FileSizeLow;
        public UInt32 NumberOfLinks;
        public UInt32 FileIndexHigh;
        public UInt32 FileIndexLow;
    }
    static void InitConsoleHandles()
    {
        SafeFileHandle hStdOut, hStdErr, hStdOutDup, hStdErrDup;
        BY_HANDLE_FILE_INFORMATION bhfi;
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        hStdErr = GetStdHandle(STD_ERROR_HANDLE);
        // Get current process handle
        IntPtr hProcess = Process.GetCurrentProcess().Handle;
        // Duplicate Stdout handle to save initial value
        DuplicateHandle(hProcess, hStdOut, hProcess, out hStdOutDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Duplicate Stderr handle to save initial value
        DuplicateHandle(hProcess, hStdErr, hProcess, out hStdErrDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Attach to console window – this may modify the standard handles
        AttachConsole(ATTACH_PARENT_PROCESS);
        // Adjust the standard handles
        if (GetFileInformationByHandle(GetStdHandle(STD_OUTPUT_HANDLE), out bhfi))
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOutDup);
        }
        else
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOut);
        }
        if (GetFileInformationByHandle(GetStdHandle(STD_ERROR_HANDLE), out bhfi))
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErrDup);
        }
        else
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErr);
        }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // initialize console handles
        InitConsoleHandles();

        if (args.Length != 0)
        {

            if (args[0].Equals("waitfordebugger"))
            {
                MessageBox.Show("Attach the debugger now");
            }
            if (args[0].Equals("version"))
            {
#if DEBUG
                String typeOfBuild = "d";
#else
                String typeOfBuild = "r";
#endif
                String output = typeOfBuild + Assembly.GetExecutingAssembly()
                    .GetName().Version.ToString();
                //Just for the fun of it
                Console.Write(output);
                Console.Beep(4000, 100);
                Console.Beep(2000, 100);
                Console.Beep(1000, 100);
                Console.Beep(8000, 100);
                return;
            }
        }
    }

I found this code here: http://www.csharp411.com/console-output-from-winforms-application/
I thought is was worthy to post it here as well.

This worked for me, to pipe the output to a file.
Call the console with

cmd /c «C:pathtoyourapplication.exe» > myfile.txt

Add this code to your application.

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool GetFileInformationByHandle(
        SafeFileHandle hFile,
        out BY_HANDLE_FILE_INFORMATION lpFileInformation
        );
    [DllImport("kernel32.dll")]
    private static extern SafeFileHandle GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(UInt32 nStdHandle, SafeFileHandle hHandle);
    [DllImport("kernel32.dll")]
    private static extern bool DuplicateHandle(
        IntPtr hSourceProcessHandle,
        SafeFileHandle hSourceHandle,
        IntPtr hTargetProcessHandle,
        out SafeFileHandle lpTargetHandle,
        UInt32 dwDesiredAccess,
        Boolean bInheritHandle,
        UInt32 dwOptions
        );
    private const UInt32 ATTACH_PARENT_PROCESS = 0xFFFFFFFF;
    private const UInt32 STD_OUTPUT_HANDLE = 0xFFFFFFF5;
    private const UInt32 STD_ERROR_HANDLE = 0xFFFFFFF4;
    private const UInt32 DUPLICATE_SAME_ACCESS = 2;
    struct BY_HANDLE_FILE_INFORMATION
    {
        public UInt32 FileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
        public UInt32 VolumeSerialNumber;
        public UInt32 FileSizeHigh;
        public UInt32 FileSizeLow;
        public UInt32 NumberOfLinks;
        public UInt32 FileIndexHigh;
        public UInt32 FileIndexLow;
    }
    static void InitConsoleHandles()
    {
        SafeFileHandle hStdOut, hStdErr, hStdOutDup, hStdErrDup;
        BY_HANDLE_FILE_INFORMATION bhfi;
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        hStdErr = GetStdHandle(STD_ERROR_HANDLE);
        // Get current process handle
        IntPtr hProcess = Process.GetCurrentProcess().Handle;
        // Duplicate Stdout handle to save initial value
        DuplicateHandle(hProcess, hStdOut, hProcess, out hStdOutDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Duplicate Stderr handle to save initial value
        DuplicateHandle(hProcess, hStdErr, hProcess, out hStdErrDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Attach to console window – this may modify the standard handles
        AttachConsole(ATTACH_PARENT_PROCESS);
        // Adjust the standard handles
        if (GetFileInformationByHandle(GetStdHandle(STD_OUTPUT_HANDLE), out bhfi))
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOutDup);
        }
        else
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOut);
        }
        if (GetFileInformationByHandle(GetStdHandle(STD_ERROR_HANDLE), out bhfi))
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErrDup);
        }
        else
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErr);
        }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // initialize console handles
        InitConsoleHandles();

        if (args.Length != 0)
        {

            if (args[0].Equals("waitfordebugger"))
            {
                MessageBox.Show("Attach the debugger now");
            }
            if (args[0].Equals("version"))
            {
#if DEBUG
                String typeOfBuild = "d";
#else
                String typeOfBuild = "r";
#endif
                String output = typeOfBuild + Assembly.GetExecutingAssembly()
                    .GetName().Version.ToString();
                //Just for the fun of it
                Console.Write(output);
                Console.Beep(4000, 100);
                Console.Beep(2000, 100);
                Console.Beep(1000, 100);
                Console.Beep(8000, 100);
                return;
            }
        }
    }

I found this code here: http://www.csharp411.com/console-output-from-winforms-application/
I thought is was worthy to post it here as well.

This worked for me, to pipe the output to a file.
Call the console with

cmd /c «C:pathtoyourapplication.exe» > myfile.txt

Add this code to your application.

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(UInt32 dwProcessId);
    [DllImport("kernel32.dll")]
    private static extern bool GetFileInformationByHandle(
        SafeFileHandle hFile,
        out BY_HANDLE_FILE_INFORMATION lpFileInformation
        );
    [DllImport("kernel32.dll")]
    private static extern SafeFileHandle GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(UInt32 nStdHandle, SafeFileHandle hHandle);
    [DllImport("kernel32.dll")]
    private static extern bool DuplicateHandle(
        IntPtr hSourceProcessHandle,
        SafeFileHandle hSourceHandle,
        IntPtr hTargetProcessHandle,
        out SafeFileHandle lpTargetHandle,
        UInt32 dwDesiredAccess,
        Boolean bInheritHandle,
        UInt32 dwOptions
        );
    private const UInt32 ATTACH_PARENT_PROCESS = 0xFFFFFFFF;
    private const UInt32 STD_OUTPUT_HANDLE = 0xFFFFFFF5;
    private const UInt32 STD_ERROR_HANDLE = 0xFFFFFFF4;
    private const UInt32 DUPLICATE_SAME_ACCESS = 2;
    struct BY_HANDLE_FILE_INFORMATION
    {
        public UInt32 FileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
        public UInt32 VolumeSerialNumber;
        public UInt32 FileSizeHigh;
        public UInt32 FileSizeLow;
        public UInt32 NumberOfLinks;
        public UInt32 FileIndexHigh;
        public UInt32 FileIndexLow;
    }
    static void InitConsoleHandles()
    {
        SafeFileHandle hStdOut, hStdErr, hStdOutDup, hStdErrDup;
        BY_HANDLE_FILE_INFORMATION bhfi;
        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        hStdErr = GetStdHandle(STD_ERROR_HANDLE);
        // Get current process handle
        IntPtr hProcess = Process.GetCurrentProcess().Handle;
        // Duplicate Stdout handle to save initial value
        DuplicateHandle(hProcess, hStdOut, hProcess, out hStdOutDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Duplicate Stderr handle to save initial value
        DuplicateHandle(hProcess, hStdErr, hProcess, out hStdErrDup,
        0, true, DUPLICATE_SAME_ACCESS);
        // Attach to console window – this may modify the standard handles
        AttachConsole(ATTACH_PARENT_PROCESS);
        // Adjust the standard handles
        if (GetFileInformationByHandle(GetStdHandle(STD_OUTPUT_HANDLE), out bhfi))
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOutDup);
        }
        else
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hStdOut);
        }
        if (GetFileInformationByHandle(GetStdHandle(STD_ERROR_HANDLE), out bhfi))
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErrDup);
        }
        else
        {
            SetStdHandle(STD_ERROR_HANDLE, hStdErr);
        }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // initialize console handles
        InitConsoleHandles();

        if (args.Length != 0)
        {

            if (args[0].Equals("waitfordebugger"))
            {
                MessageBox.Show("Attach the debugger now");
            }
            if (args[0].Equals("version"))
            {
#if DEBUG
                String typeOfBuild = "d";
#else
                String typeOfBuild = "r";
#endif
                String output = typeOfBuild + Assembly.GetExecutingAssembly()
                    .GetName().Version.ToString();
                //Just for the fun of it
                Console.Write(output);
                Console.Beep(4000, 100);
                Console.Beep(2000, 100);
                Console.Beep(1000, 100);
                Console.Beep(8000, 100);
                return;
            }
        }
    }

I found this code here: http://www.csharp411.com/console-output-from-winforms-application/
I thought is was worthy to post it here as well.

  • Remove From My Forums
  • Question

  • Hello i use vs2015 ent update3….

    i have project windows forms application in C++/CLI, how to open console in winform application?

    also i have a code in c# and working

    here code from c#

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace Testw
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                AllocConsole();
            }
            // Allows the command line to be seen during normal execution
            [DllImport("kernel32.dll", SetLastError = true)]
            [return: MarshalAsAttribute(UnmanagedType.Bool)]
            static extern bool AllocConsole();
        }
    }

    i try translate the code  from c# to C++/CLI but not working….

    and my code in C++/CLI

    MyForm.h
    
    #pragma once
    
    namespace TestP {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    	using namespace System::Runtime::InteropServices;
    
    	/// <summary>
    	/// Summary for MyForm
    	/// </summary>
    	public ref class MyForm : public System::Windows::Forms::Form
    	{
    	public:
    		MyForm(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			//
    		}
    
    #pragma endregion
    	private: System::Void MyForm_Load(System::Object^  sender, System::EventArgs^  e) {
    	}
      
    			 [DllImport("kernel32.dll" SetLastError = true)] //Error attributes are not allowed here    
    
    }; //Error expected a declaration
    }

    Any help pls? how to translate…. ty 

Answers

  • Try this —

    namespace MyForm {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    	using namespace System::Runtime::InteropServices;
    
    	namespace Win32 {
    		[DllImport("kernel32.dll", CallingConvention = CallingConvention::StdCall)]
    		int AllocConsole();
    		[DllImport("kernel32.dll", CallingConvention = CallingConvention::StdCall)]
    		int FreeConsole();
    	}
    
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Clean up any resources being used.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::Button^  button1;
    	private: System::Windows::Forms::Button^  button2;
    	protected:
    
    
    
    	protected:
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->button1 = (gcnew System::Windows::Forms::Button());
    			this->button2 = (gcnew System::Windows::Forms::Button());
    			this->SuspendLayout();
    			// 
    			// button1
    			// 
    			this->button1->Location = System::Drawing::Point(105, 45);
    			this->button1->Name = L"button1";
    			this->button1->Size = System::Drawing::Size(94, 23);
    			this->button1->TabIndex = 1;
    			this->button1->Text = L"AllocConsole";
    			this->button1->UseVisualStyleBackColor = true;
    			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
    			// 
    			// button2
    			// 
    			this->button2->Location = System::Drawing::Point(105, 133);
    			this->button2->Name = L"button2";
    			this->button2->Size = System::Drawing::Size(94, 23);
    			this->button2->TabIndex = 2;
    			this->button2->Text = L"FreeConsole";
    			this->button2->UseVisualStyleBackColor = true;
    			this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(284, 262);
    			this->Controls->Add(this->button2);
    			this->Controls->Add(this->button1);
    			this->Name = L"Form1";
    			this->Text = L"Form1";
    			this->ResumeLayout(false);
    
    		}
    #pragma endregion
    	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
    	{
    		int rc = Win32::AllocConsole();
    	}
    	private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) 
    	{
    		int rc = Win32::FreeConsole();
    	}
    	};
    }
    • Edited by

      Friday, September 9, 2016 11:42 PM

    • Marked as answer by
      d22xxxx
      Saturday, September 10, 2016 12:06 AM

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

1

26.12.2010, 12:18. Показов 73596. Ответов 13


Необходимо при работе win приложения вызывать консоль для ввода/вывода данных.
Реально ли это вообще сделать ?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

26.12.2010, 12:18

13

zalogic

194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 12:28

2

конечно реально. Какую именно консоль?

если просто консольное приложение надо:

C#
1
System.Diagnostics.Process.Start(Application.StartupPath + @"gr.exe");

1

Иван_007

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 12:36

 [ТС]

3

Цитата
Сообщение от zalogic
Посмотреть сообщение

Какую именно консоль?

Обычную консоль, как в консольном приложении.

Например ,что-бы считать данные можно было так :

C#
1
Console.ReadLine();

0

194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 12:45

4

Цитата
Сообщение от Иван_007
Посмотреть сообщение

Например ,что-бы считать данные можно было так :

как вызвать я написал, а как обеспечить синхронизацию ,сам придумай. Варианты есть разные.
Можешь через временный фаил.

Вот ещё почитай, хотя там тоже самое что я написал.
Запуск консольного приложения из WindowsForm

или ты как объект(класс объявить) хочешь в винформсе создать консль?

0

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 12:56

 [ТС]

5

Цитата
Сообщение от zalogic
Посмотреть сообщение

или ты как объект(класс объявить) хочешь в винформсе создать консль?

Именно это и хочу .

Идея в следующем :

Есть основная форма . В определенный момент она должна открыть консоль и считать оттуда введенные данные .

0

zalogic

194 / 193 / 15

Регистрация: 12.12.2010

Сообщений: 270

26.12.2010, 13:12

6

хмм…

C#
1
using System.Console;

пространство для консолей. Как создать не скажу. Но куча есть обратных задач из консольного -> винформс (н-р http://theseus.blog.ru/91016531.html). Может как-то на их основе.

0

NickoTin

Почетный модератор

Эксперт .NET

8713 / 3665 / 404

Регистрация: 14.06.2010

Сообщений: 4,513

Записей в блоге: 9

26.12.2010, 14:48

7

Лучший ответ Сообщение было отмечено как решение

Решение

Иван_007, можно с помощью WinAPI:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Runtime.InteropServices;
...
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole ();
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool FreeConsole ();
...
        /* где-нибудь в кнопке, а лучше в отдельном потоке
         * т.к. во время чтения из консоли основной поток
         * приложения будет заморожен */
        if (AllocConsole()) {
            Console.WriteLine("Ввод данных");
            Console.ReadLine();
            FreeConsole();
        }

p.s. У приложения всего может быть только одно окно с консолью, так что одновременный вызов AllocConsole в нескольких местах не приведет к созданию нового окна.

12

Unril

821 / 712 / 110

Регистрация: 06.10.2010

Сообщений: 825

Записей в блоге: 1

26.12.2010, 16:18

8

Лучший ответ Сообщение было отмечено как решение

Решение

К примеру можно сделать так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApplicationTest
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            // Запускаем поток с консолью.
            Task.Factory.StartNew(Console);
        }
 
        private void Console()
        {
            // Запускаем консоль.
            if (AllocConsole())
            {
                System.Console.WriteLine("Для выхода наберите exit.");
                while (true)
                {
                    // Считываем данные.
                    string output = System.Console.ReadLine();
                    if (output == "exit")
                        break;
                    // Выводим данные в textBox
                    Action action = () => textBox.Text += output + Environment.NewLine;
                    if (InvokeRequired)
                        Invoke(action);
                    else
                        action();
                }
                // Закрываем консоль.
                FreeConsole();
            }
        }
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool AllocConsole();
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FreeConsole();
    }
}

8

27 / 27 / 14

Регистрация: 20.05.2009

Сообщений: 80

26.12.2010, 17:29

 [ТС]

9

Unril,
SSTREGG,

Спасибо огромное ,именно то что нужно было.

0

0 / 0 / 1

Регистрация: 08.11.2012

Сообщений: 11

26.10.2014, 22:40

10

СПАСИБО, вызов консоли в событии клика кнопки, а затем продолжение работы кода формы РАБОТАЕТ!!!

0

grupetto

0 / 0 / 0

Регистрация: 28.11.2015

Сообщений: 4

23.10.2016, 14:28

11

А где вы инфу по таким вещам берете? Имею в виду:

C#
1
2
3
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

В Шилдте или Троелсене такого вроде нет.

И вопрос — когда создается консольное приложение то тоже импортируется эта библиотека?

0

134 / 130 / 107

Регистрация: 17.03.2009

Сообщений: 364

23.10.2016, 22:23

12

Цитата
Сообщение от grupetto
Посмотреть сообщение

А где вы инфу по таким вещам берете? Имею в виду:

Ну, я, например на стеке нашел за пару секунд.

0

975 / 870 / 350

Регистрация: 26.04.2012

Сообщений: 2,647

24.10.2016, 08:26

13

0

Enflamed

3 / 3 / 1

Регистрация: 12.04.2015

Сообщений: 74

19.12.2016, 05:59

14

Цитата
Сообщение от grupetto
Посмотреть сообщение

где вы инфу по таким вещам берете? Имею в виду:

C#
1
2
3
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

Это не C#, это winapi. Поэтому в Шилдте и нету. WinApi, насколько я знаю, написаны на C++.
То есть, по сути, мы используем импорт куска кода из C++ при компиляции программы… Вообще, Вы правы, в обучающих курсах и книгах по C# часто вообще ни слова про p/invoke. Я лично считаю, что эту тему необходимо изучать ещё до того, как начал создание приложений с пользовательским интерфейсом.

0

Вопросом таким я озадачился, читая ВиО. Поискал по интернету и нашёл solution здесь.

Для тестирования создал пустой проект Windows Forms C#. Добавал класс:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

    class Win32
    {
        /// <summary>
        /// Allocates a new console for current process.
        /// </summary>
        [DllImport("kernel32.dll")]
        public static extern Boolean AllocConsole();

        /// <summary>
        /// Frees the console.
        /// </summary>
        [DllImport("kernel32.dll")]
        public static extern Boolean FreeConsole();
    }

В конструктор формы добавил:

        public Form1()
        {
            InitializeComponent();

            Win32.AllocConsole();
            Console.WriteLine("Hello worldn");
        }

См. также

  • http://stackoverflow.com/questions/472282/show-console-in-windows-application
  • http://reg2run.svn.sourceforge.net/viewvc/reg2run/trunk/ManualConsole.cs?view=markup
  • http://www.nerdyhearn.com/blog/157
  • Как открыть командную строку windows 10 pro
  • Как открыть калькулятор в windows 10 с помощью клавиатуры
  • Как открыть консоль mysql в windows
  • Как открыть командную строку в windows 7 при загрузке компьютера
  • Как открыть ком порт на windows 10