Вывод в консоль 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.

zakaz_77

9 / 9 / 4

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

Сообщений: 730

1

17.06.2017, 09:01. Показов 14195. Ответов 3

Метки ado.net, cs0122 (Все метки)


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

Сценарий.
1. Windows Forms. Подключаемся к БД.
2. Windows Forms. Создаём ДатаТабле.
3. Windows Forms. Нажимаем кнопку для вывода списка полей ДатаТабле.
4. Console. Выводим в Console список полей ДатаТабле.

Код Windows Forms.

Кликните здесь для просмотра всего текста

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
50
51
52
53
54
55
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.con
 
// АКСЕС
using System.Data.OleDb;
 
// MySql
using MySql.Data.MySqlClient;
using System.Threading; // ПОТОКИ
namespace rsh
{
    public partial class Form1 : Form
    {
        DataTable dt_025;
 
        BindingSource bs_025;
         public void fnk_dt_025()
        {
            dt_025 = new DataTable();
            bs_025 = new BindingSource();
 
            fnk_MySqlComNQry_dtaAdpt(); // Мускул
            MySqlDtAdp_0.Fill(dt_025); // -> DataTable
 
            bs_025.DataSource = dt_025; // -> BindingSource
        }
        
        
         private void button63_Click(object sender, EventArgs e) // создание ДТ. Вывод в dataGridView1
        {
            tbl_name = textBox115.Text; // Имя редактируемой таблицы. Пирсваивае значение переменной
 
            fnk_select_All_zpr_01(); // SRLECT выполняем запрос
 
            fnk_dt_025(); // создание ДТ
 
            dataGridView1.DataSource = bs_025;  // dataGridView1. Загружаем Дататбле
            textBox97.Text = textBox115.Text;
        }
        
        private void button70_Click(object sender, EventArgs e)
        {
            Program.Test();
        } // вывод списка полей (столбцов) в консоль
    }
}

Код Console

Кликните здесь для просмотра всего текста

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
 
//ДОБАВЛЕНО
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
 
 
namespace rsh
{
    static class Program
    {
        /// <summary>
        /// Главная точка входа для приложения.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
 
        public static void Test()
        {
            // Console.WriteLine("Test");
             foreach (DataColumn column in Form1.dt_025.Columns)
                Console.Write("\t{0}", column.ColumnName);
 
        }
 
    }
}

Приведённый код выдаёт ошибку
Ошибка
Ошибка CS0122 ‘Form1.dt_025″ недоступен из-за его уровня защиты.

Вопрос
1. Как правильно организовать код, чтобы можно было вывести список полей в консоль?
2. При наличии, другие замечания по организации кода?



0



RunningMan

278 / 186 / 75

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

Сообщений: 1,088

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

17.06.2017, 10:43

2

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

1. Как правильно организовать код, чтобы можно было вывести список полей в консоль?

Там где у вас код Windows Forms (Form1.cs)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
 private void button70_Click(object sender, EventArgs e)
 {
        Test();
 } 
 
// вывод списка полей (столбцов) в консоль
 public void Test()
 {
        // Console.WriteLine("Test");
         foreach (DataColumn column in this.dt_025.Columns)
              Console.Write("\t{0}", column.ColumnName);
 
 }



1



9 / 9 / 4

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

Сообщений: 730

17.06.2017, 11:04

 [ТС]

3

RuningMan,
Сделал согласно вашей рекомендации.
Нажимаю «button70», никакой реакции.
Ошибок нет.
Консоль не запускается.

Может что-нибудь ещё нужно сделать?



0



278 / 186 / 75

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

Сообщений: 1,088

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

17.06.2017, 11:38

4

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

Решение

Так у вас консоль не открыта ещё?
Нет у меня студии чтобы показать.
В свойствах проекта нужно выбрать приложение не Windows
а Console.

Только при таких настройках, консоль будет открыта с самого запуска приложения.

Добавлено через 4 минуты
Вам нужно консоль по нажатию кнопки открыть?

Вот ещё поискал

Вызов консоли в WinForm приложении



1



Jun 04

You may wish to enable your WinForms application to run from a console window or command line. And when it does, you probably want to send output messages to the console window that launched your WinForms application.

Unfortunately Console.WriteLine()–the standard method of writing to the console window–by default will not work from a WinForms application. That’s because the console window that launched your WinForms application belongs to the cmd.exe process, which is separate from your WinForms application process.

So to redirect output from a WinForms application to the console window that launched it, use the AttachConsole Win32 method introduced in Windows XP. AttachConsole attaches the current process to the console window of another process. The special parameter ATTACH_PARENT_PROCESS attaches to the parent process, which in this case is the console window that launched the WinForms application.

Simple Example

Following is a simple WinForms application that redirects its output to the console window that launched it:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MyWinFormsApp
{
    static class Program
    {
        [DllImport( "kernel32.dll" )]
        static extern bool AttachConsole( int dwProcessId );
        private const int ATTACH_PARENT_PROCESS = -1;

        [STAThread]
        static void Main( string[] args )
        {
            // redirect console output to parent process;
            // must be before any calls to Console.WriteLine()
            AttachConsole( ATTACH_PARENT_PROCESS );

            // to demonstrate where the console output is going
            int argCount = args == null ? 0 : args.Length;
            Console.WriteLine( "nYou specified {0} arguments:", argCount );
            for (int i = 0; i < argCount; i++)
            {
                Console.WriteLine( "  {0}", args[i] );
            }

            // launch the WinForms application like normal
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault( false );
            Application.Run( new Form1() );
        }
    }
}

One Gotcha

There is one problem with this approach. If you redirect the console window output to a text file, for example using the redirect arrow:

MyWinFormsApp.exe >output.txt arg1 arg2

In this case, output will not redirect to the “output.txt” text file as expected, but instead will continue to appear in the console window. Please comment if you have a solution to this issue.

There are basically two things that can happen here.

  1. Console output

It is possible for a winforms program to attach itself to the console window that created it (or to a different console window, or indeed to a new console window if desired). Once attached to the console window Console.WriteLine() etc works as expected. One gotcha to this approach is that the program returns control to the console window immediately, and then carries on writing to it, so the user can also type away in the console window. You can use start with the /wait parameter to handle this I think.

Start commsnd syntax

  1. Redirected console output

This is when someone pipes the output from your program somewhere else, eg.

yourapp > file.txt

Attaching to a console window in this case effectively ignores the piping. To make this work you can call Console.OpenStandardOutput() to get a handle to the stream that the output should be piped to. This only works if the output is piped, so if you want to handle both of the scenarios you need to open the standard output and write to it and attach to the console window. This does mean that the output is sent to the console window and to the pipe but its the best solution I could find. Below the code I use to do this.

// This always writes to the parent console window and also to a redirected stdout if there is one.
// It would be better to do the relevant thing (eg write to the redirected file if there is one, otherwise
// write to the console) but it doesn't seem possible.
public class GUIConsoleWriter : IConsoleWriter
{
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int dwProcessId);

    private const int ATTACH_PARENT_PROCESS = -1;

    StreamWriter _stdOutWriter;
  
    // this must be called early in the program
    public GUIConsoleWriter()
    {
        // this needs to happen before attachconsole.
        // If the output is not redirected we still get a valid stream but it doesn't appear to write anywhere
        // I guess it probably does write somewhere, but nowhere I can find out about
        var stdout = Console.OpenStandardOutput();
        _stdOutWriter = new StreamWriter(stdout);
        _stdOutWriter.AutoFlush = true;

        AttachConsole(ATTACH_PARENT_PROCESS);
    }

    public void WriteLine(string line)
    {
        _stdOutWriter.WriteLine(line);
        Console.WriteLine(line);
    }
}

  • Remove From My Forums
  • Question

  • Alright, I’ve been searching but I can’t find anything related to my question… I need to use a Console with my Windows Form (for debug purposes). How do I «add» a Console?

    Another thing… I need to find out how to make a rich text box unwritable.

    Thanks!

Answers

  • You can dynamically create and destroy a console window using PInvoke to call the Windows API:

    [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();
     

    Just declare those, and then call AllocConsole() to create a console and FreeConsole() to get rid of it. While you have a console, Console.WriteLine() etc will work.

  • Выберите элемент чтобы зафиксировать как убрать windows 10
  • Выбрать приложение по умолчанию windows 10
  • Вывести содержимое файла windows cmd
  • Выбор устройства воспроизведения windows 10
  • Выдает синий экран при запуске windows