How do I show a console output/window in a forms application?

前端 未结 11 1497
我寻月下人不归
我寻月下人不归 2020-11-22 11:15

To get stuck in straight away, a very basic example:

using System;
using System.Windows.Forms;

class test
{ 
    static void Main()
    { 
        Console.W         


        
相关标签:
11条回答
  • 2020-11-22 12:00

    You can any time switch between type of applications, to console or windows. So, you will not write special logic to see the stdout. Also, when running application in debugger, you will see all the stdout in output window. You might also just add a breakpoint, and in breakpoint properties change "When Hit...", you can output any messages, and variables. Also you can check/uncheck "Continue execution", and your breakpoint will become square shaped. So, the breakpoint messages without changhing anything in the application in the debug output window.

    0 讨论(0)
  • 2020-11-22 12:03

    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.

    0 讨论(0)
  • 2020-11-22 12:03

    Create a Windows Forms Application, and change the output type to Console.

    It will result in both a console and the form to open.

    0 讨论(0)
  • 2020-11-22 12:04
    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));
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:05

    this one should work.

    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();
    
    0 讨论(0)
提交回复
热议问题