Как показать консольный вывод / окно в приложении форм?

Чтобы застрять сразу, очень простой пример:

using System; using System.Windows.Forms; class test { static void Main() { Console.WriteLine("test"); MessageBox.Show("test"); } } 

Если я скомпилирую это с настройками по умолчанию (используя csc в командной строке), как и ожидалось, он будет компилироваться в консольное приложение. Кроме того, поскольку я импортировал System.Windows.Forms , он также отобразит окно сообщения.

Теперь, если я использую параметр /target:winexe , который, я думаю, такой же, как выбор Windows Application из вариантов проекта, как и ожидалось, я буду видеть только окно сообщения и не выводить консоль.

(Фактически, момент, когда он запускается из командной строки, я могу выполнить следующую команду до того, как приложение даже завершится).

Итак, мой вопрос: я знаю, что вы можете иметь «windows» / формы, выводимые из консольного приложения, но все равно, чтобы показать консоль из приложения Windows?

этот должен работать.

 using System.Runtime.InteropServices; private void Form1_Load(object sender, EventArgs e) { AllocConsole(); } [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool AllocConsole(); 

Возможно, это слишком упрощенно …

Создайте проект Windows Form …

Затем: Свойства проекта -> Приложение -> Тип вывода -> Консольное приложение

Затем может работать Консоль и Формы, работает для меня

Если вы не беспокоитесь об открытии консоли в команде, вы можете перейти к свойствам своего проекта и изменить его на консольное приложение

снимок экрана об изменении типа проекта ,

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

Не забудьте выключить его, прежде чем развертывать программу.

Вы можете вызвать AttachConsole с помощью pinvoke, чтобы получить окно консоли, подключенное к проекту WinForms: http://www.csharp411.com/console-output-from-winforms-application/

Вы также можете рассмотреть Log4net ( http://logging.apache.org/log4net/index.html ) для настройки вывода журнала в разных конфигурациях.

Это сработало для меня, чтобы передать вывод в файл. Вызовите консоль с помощью

cmd / c “C: \ path \ to \ your \ application.exe”> myfile.txt

Добавьте этот код в свою заявку.

  [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); } } ///  /// The main entry point for the application. ///  [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")) { String TypeOfBuild = ""; #if DEBUG TypeOfBuild = "d"; #else 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; } } } 

Я нашел этот код здесь: http://www.csharp411.com/console-output-from-winforms-application/ Я подумал, что было достойно опубликовать его здесь.

Здесь есть две вещи.

Консольный выход. Программа winforms может присоединяться к окну консоли, который ее создал (или к другому консольному окну или, если нужно, новому окну консоли). После подключения к консольному окну Console.WriteLine () и т. Д. Работает так, как ожидалось. Одна из них заключается в том, что программа немедленно возвращает управление в консольное окно, а затем продолжает записывать на нее, поэтому пользователь может также ввести в консольное окно. Вы можете использовать start с параметром / wait для обработки этого, я думаю.

Ссылка для запуска синтаксиса команды

Перенаправленный вывод консоли. Это когда кто-то передает данные из вашей программы в другом месте, например.

yourapp> file.txt

Прикрепление к консольному окну в этом случае эффективно игнорирует трубопровод. Чтобы выполнить эту работу, вы можете вызвать Console.OpenStandardOutput (), чтобы получить дескриптор streamа, к которому должен быть подключен вывод. Это работает только в том случае, если вывод передан по каналам, поэтому, если вы хотите обрабатывать оба сценария, вам нужно открыть стандартный вывод и записать на него и прикрепить к консольному окну. Это означает, что вывод отправляется в окно консоли и в трубку, но это лучшее решение, которое я могу найти. Ниже кода, который я использую для этого.

 // 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); } } 
 using System; using System.Runtime.InteropServices; namespace SomeProject { class GuiRedirect { [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(StandardHandle nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] private static extern FileType GetFileType(IntPtr handle); private enum StandardHandle : uint { Input = unchecked((uint)-10), Output = unchecked((uint)-11), Error = unchecked((uint)-12) } private enum FileType : uint { Unknown = 0x0000, Disk = 0x0001, Char = 0x0002, Pipe = 0x0003 } private static bool IsRedirected(IntPtr handle) { FileType fileType = GetFileType(handle); return (fileType == FileType.Disk) || (fileType == FileType.Pipe); } public static void Redirect() { if (IsRedirected(GetStdHandle(StandardHandle.Output))) { var initialiseOut = Console.Out; } bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error)); if (errorRedirected) { var initialiseError = Console.Error; } AttachConsole(-1); if (!errorRedirected) SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output)); } } 
 //From your application set the Console to write to your RichTextkBox //object: Console.SetOut(new RichTextBoxWriter(yourRichTextBox)); //To ensure that your RichTextBox object is scrolled down when its text is //changed add this event: private void yourRichTextBox_TextChanged(object sender, EventArgs e) { yourRichTextBox.SelectionStart = yourRichTextBox.Text.Length; yourRichTextBox.ScrollToCaret(); } public delegate void StringArgReturningVoidDelegate(string text); public class RichTextBoxWriter : TextWriter { private readonly RichTextBox _richTextBox; public RichTextBoxWriter(RichTextBox richTexttbox) { _richTextBox = richTexttbox; } public override void Write(char value) { SetText(value.ToString()); } public override void Write(string value) { SetText(value); } public override void WriteLine(char value) { SetText(value + Environment.NewLine); } public override void WriteLine(string value) { SetText(value + Environment.NewLine); } public override Encoding Encoding => Encoding.ASCII; //Write to your UI object in thread safe way: private void SetText(string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (_richTextBox.InvokeRequired) { var d = new StringArgReturningVoidDelegate(SetText); _richTextBox.Invoke(d, text); } else { _richTextBox.Text += text; } } } 

Вы можете в любое время переключаться между типами приложений, консолями или windowsми. Таким образом, вы не будете писать специальную логику, чтобы увидеть stdout. Кроме того, при запуске приложения в отладчике вы увидите все stdout в окне вывода. Вы также можете просто добавить точку останова, а в свойствах точки останова «When Hit …» вы можете выводить любые сообщения и переменные. Также вы можете проверить / снять флажок «Продолжить выполнение», и ваша точка останова станет квадратной. Таким образом, сообщения точки останова без изменения чего-либо в приложении в окне вывода отладки.

  • #ifdef #ifndef в Java
  • Как скомпилировать сценарий оболочки Linux как автономный исполняемый * двоичный * (т. Е. Не только, например, chmod 755)?
  • Почему JVM-кеш JIT-скомпилированный код?
  • Что такое объектный файл в C?
  • вопросы об управлении именами в C ++
  • C ++, объявление переменной в выражении 'if'
  • Почему я получаю ошибку компиляции «org / codehaus / groovy / control / CompilationFailedException»?
  • запустить программу с несколькими исходными файлами в компиляторе GNU c ++
  • Статические конечные значения Java заменяются в коде при компиляции?
  • Как вы сокращаете время компиляции и связываете время для проектов Visual C ++ (собственный C ++)?
  • Как связать файлы объектов в C? Ошибка с «Неопределенные символы для архитектуры x86_64»
  • Давайте будем гением компьютера.