162 votes

Comment afficher une sortie / fenêtre de console dans une application de formulaire?

Pour obtenir coincé tout de suite, un exemple très simple:

using System;
using System.Windows.Forms;

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

Si je le compiler avec les options par défaut (à l'aide de csc à la ligne de commande), comme prévu, il sera de compiler une application console. Aussi, parce que j'ai importé System.Windows.Forms, il sera également afficher une boîte de message.

Maintenant, si j'utilise l'option /target:winexe, ce qui je pense est le même que le choix d' Windows Application de dans les options du projet, comme prévu, je vais seulement voir la Boîte de Message et pas de sortie de la console.

(En fait, au moment où il est lancé à partir de la ligne de commande, je ne peux émettre la commande suivante avant que l'application n'a même pas terminé).

Donc, ma question est - je sais que vous pouvez avoir "windows"/les formes de la sortie d'une application console, mais est-il de toute façon à afficher la console à partir d'une application Windows?

188voto

wizzardz Points 1661

celui-ci devrait fonctionner.

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

80voto

gunr2171 Points 4327

Si vous ne souhaitez pas ouvrir une console à la commande, vous pouvez accéder aux propriétés de votre projet et le modifier en Console Application .

Cela montrera toujours votre formulaire et ouvrira une fenêtre de console. Vous ne pouvez pas fermer la fenêtre de la console, mais cela fonctionne comme un excellent enregistreur pour le débogage.

Rappelez-vous simplement de le désactiver avant de déployer le programme.

20voto

Adam Vandenberg Points 8098

Vous pouvez appeler AttachConsole utilisant pinvoke pour obtenir une fenêtre de console associée à un projet WinForms: http://www.csharp411.com/console-output-from-winforms-application/

Vous pouvez également envisager d’utiliser Log4net ( http://logging.apache.org/log4net/index.html ) pour configurer la sortie du journal dans différentes configurations.

14voto

Mike de Klerk Points 1606

Cela a fonctionné pour moi, pour diriger la sortie vers un fichier. Appeler la console avec

cmd / c "C: \ chemin \ vers \ votre \ application.exe"> myfile.txt

Ajoutez ce code à votre 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"))
            {
                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;
            }
        }
    }
 

J'ai trouvé ce code ici: http://www.csharp411.com/console-output-from-winforms-application/ Je pensais qu'il était digne de le poster ici aussi.

11voto

cedd Points 241

Il existe essentiellement deux choses qui peuvent se produire ici.

Sortie de la Console Il est possible pour un winforms programme de s'attacher à la fenêtre de la console qui l'a créé (ou à une autre fenêtre de la console, ou bien à une nouvelle fenêtre de console, si désiré). Une fois fixé à la fenêtre de la console la Console.WriteLine (), etc fonctionne comme prévu. Un piège de cette approche est que le programme retourne le contrôle à la fenêtre de la console immédiatement, et l'emporte alors sur l'écriture, de sorte que l'utilisateur peut taper dans la fenêtre de la console. Vous pouvez utiliser de commencer avec le /attente de paramètre à gérer ce que je pense.

Lien pour démarrer la syntaxe de la Commande

Redirigé de sortie de la console C'est lorsque quelqu'un a des tuyaux à la sortie de votre programme de quelque part d'autre, par exemple.

yourapp > file.txt

L'attachement à une fenêtre de la console dans ce cas ne tient pas compte de la tuyauterie. Pour faire ce travail, vous pouvez appeler la Console.OpenStandardOutput() pour obtenir un handle vers le flux de sortie doit être canalisée. Cela fonctionne uniquement si la sortie est joué, donc si vous souhaitez gérer à la fois des scénarios, vous devez ouvrir la sortie standard et de l'écriture et de l'attacher à la fenêtre de la console. Cela signifie que la sortie est envoyé à la fenêtre de la console et à la pipe, mais c'est la meilleure solution que j'ai pu trouver. Ci-dessous le code que j'utilise pour ce faire.

// 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);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X