web-dev-qa-db-fra.com

Pas de sortie vers la console depuis une application WPF?

J'utilise Console.WriteLine () à partir d'une application de test WPF très simple, mais lorsque j'exécute l'application à partir de la ligne de commande, rien ne s'affiche en écriture sur la console. Est-ce que quelqu'un sait ce qui pourrait se passer ici?

Je peux le reproduire en créant une application WPF dans VS 2008 et en ajoutant simplement Console.WriteLine ("text") à tout endroit exécuté. Des idées?

Tout ce dont j'ai besoin pour le moment est quelque chose d'aussi simple que Console.WriteLine (). Je réalise que je pourrais utiliser log4net ou une autre solution de journalisation, mais je n’ai vraiment pas besoin de tant de fonctionnalités pour cette application.

Edit: J'aurais dû me rappeler que Console.WriteLine () est destiné aux applications console. Oh bien, pas de questions stupides, non? :-) Je vais juste utiliser System.Diagnostics.Trace.WriteLine () et DebugView pour le moment.

97
Rob

Vous devrez créer une fenêtre de console manuellement avant d'appeler des méthodes Console.Write. Cela permettra à la console de fonctionner correctement sans changer le type de projet (ce qui pour l'application WPF ne fonctionnera pas).

Voici un exemple complet de code source, montrant à quoi une classe ConsoleManager pourrait ressembler et comment l’utiliser pour activer/désactiver la console, indépendamment du type de projet.

Avec la classe suivante, il vous suffit d’écrire ConsoleManager.Show() quelque part avant tout appel à Console.Write...

[SuppressUnmanagedCodeSecurity]
public static class ConsoleManager
{
    private const string Kernel32_DllName = "kernel32.dll";

    [DllImport(Kernel32_DllName)]
    private static extern bool AllocConsole();

    [DllImport(Kernel32_DllName)]
    private static extern bool FreeConsole();

    [DllImport(Kernel32_DllName)]
    private static extern IntPtr GetConsoleWindow();

    [DllImport(Kernel32_DllName)]
    private static extern int GetConsoleOutputCP();

    public static bool HasConsole
    {
        get { return GetConsoleWindow() != IntPtr.Zero; }
    }

    /// <summary>
    /// Creates a new console instance if the process is not attached to a console already.
    /// </summary>
    public static void Show()
    {
        //#if DEBUG
        if (!HasConsole)
        {
            AllocConsole();
            InvalidateOutAndError();
        }
        //#endif
    }

    /// <summary>
    /// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown.
    /// </summary>
    public static void Hide()
    {
        //#if DEBUG
        if (HasConsole)
        {
            SetOutAndErrorNull();
            FreeConsole();
        }
        //#endif
    }

    public static void Toggle()
    {
        if (HasConsole)
        {
            Hide();
        }
        else
        {
            Show();
        }
    }

    static void InvalidateOutAndError()
    {
        Type type = typeof(System.Console);

        System.Reflection.FieldInfo _out = type.GetField("_out",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        System.Reflection.FieldInfo _error = type.GetField("_error",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        Debug.Assert(_out != null);
        Debug.Assert(_error != null);

        Debug.Assert(_InitializeStdOutError != null);

        _out.SetValue(null, null);
        _error.SetValue(null, null);

        _InitializeStdOutError.Invoke(null, new object[] { true });
    }

    static void SetOutAndErrorNull()
    {
        Console.SetOut(TextWriter.Null);
        Console.SetError(TextWriter.Null);
    }
} 
90
John Leidegren

Faites un clic droit sur le projet, "Propriétés", "Application", sélectionnez "Type de sortie" et choisissez "Application console". Une console sera également installée.

117
Brian

Vous pouvez utiliser

Trace.WriteLine("text");

Cela sera affiché dans la fenêtre "Sortie" de Visual Studio (lors du débogage).

assurez-vous que l’ensemble de diagnostics est inclus:

using System.Diagnostics;
107
Phobis

Bien que John Leidegren continue à abattre cette idée, Brian a raison. Je viens de le faire fonctionner dans Visual Studio.

Pour être clair, une application WPF ne crée pas de fenêtre console par défaut.

Vous devez créer une application WPF, puis définir le type de sortie "Application console". Lorsque vous exécutez le projet, vous verrez une fenêtre de console avec votre fenêtre WPF devant elle.

Cela ne semble pas très joli, mais je l’ai trouvé utile car je voulais que mon application soit exécutée à partir de la ligne de commande avec des commentaires, puis, pour certaines options de commande, la fenêtre WPF était affichée.

10
antidemon

Il est possible de voir la sortie destinée à la console en utilisant redirection en ligne de commande .

Par exemple:

C:\src\bin\Debug\Example.exe > output.txt

va écrire tout le contenu à output.txt fichier.

9
Lu55

Ancien post, mais je me suis heurté à cela. Si vous essayez d'exporter quelque chose dans Output dans un projet WPF dans Visual Studio, la méthode contemporaine est la suivante:

Inclure ceci:

using System.Diagnostics;

Et alors:

Debug.WriteLine("something");
7
Smitty

J'utilise Console.WriteLine () pour une utilisation dans la fenêtre de sortie ...

3
erodewald

J'ai créé une solution, mélangé les informations de varius post.

C'est un formulaire qui contient une étiquette et une zone de texte. La sortie de la console est redirigée vers la zone de texte.

Il existe également une classe appelée ConsoleView qui implémente trois méthodes publiques: Show (), Close () et Release (). Le dernier est pour laisser ouvrir la console et activez le bouton Fermer pour afficher les résultats.

Les formulaires s'appellent FrmConsole. Voici le code XAML et le code c #.

L'utilisation est très simple:

ConsoleView.Show("Title of the Console");

Pour ouvrir la console. Utilisation:

System.Console.WriteLine("The debug message");

Pour le texte en sortie sur la console.

Utilisation:

ConsoleView.Close();

Pour fermer la console.

ConsoleView.Release();

Laisse ouvrir la console et active le bouton Fermer

XAML

<Window x:Class="CustomControls.FrmConsole"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:CustomControls"
    mc:Ignorable="d"
    Height="500" Width="600" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Topmost="True" Icon="Images/icoConsole.png">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="40"/>
    </Grid.RowDefinitions>
    <Label Grid.Row="0" Name="lblTitulo" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" FontFamily="Arial" FontSize="14" FontWeight="Bold" Content="Titulo"/>
    <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="10"/>
        </Grid.ColumnDefinitions>
        <TextBox Grid.Column="1" Name="txtInner" FontFamily="Arial" FontSize="10" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" TextWrapping="Wrap"/>
    </Grid>
    <Button Name="btnCerrar" Grid.Row="2" Content="Cerrar" Width="100" Height="30" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center"/>
</Grid>

Le code de la fenêtre:

partial class FrmConsole : Window
{
    private class ControlWriter : TextWriter
    {
        private TextBox textbox;
        public ControlWriter(TextBox textbox)
        {
            this.textbox = textbox;
        }

        public override void WriteLine(char value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value.ToString());
                textbox.AppendText(Environment.NewLine);
                textbox.ScrollToEnd();
            }));
        }

        public override void WriteLine(string value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value);
                textbox.AppendText(Environment.NewLine);
                textbox.ScrollToEnd();
            }));
        }

        public override void Write(char value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value.ToString());
                textbox.ScrollToEnd();
            }));
        }

        public override void Write(string value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value);
                textbox.ScrollToEnd();
            }));
        }

        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }

        }
    }

    //DEFINICIONES DE LA CLASE
    #region DEFINICIONES DE LA CLASE

    #endregion


    //CONSTRUCTORES DE LA CLASE
    #region CONSTRUCTORES DE LA CLASE

    public FrmConsole(string titulo)
    {
        InitializeComponent();
        lblTitulo.Content = titulo;
        Clear();
        btnCerrar.Click += new RoutedEventHandler(BtnCerrar_Click);
        Console.SetOut(new ControlWriter(txtInner));
        DesactivarCerrar();
    }

    #endregion


    //PROPIEDADES
    #region PROPIEDADES

    #endregion


    //DELEGADOS
    #region DELEGADOS

    private void BtnCerrar_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }

    #endregion


    //METODOS Y FUNCIONES
    #region METODOS Y FUNCIONES

    public void ActivarCerrar()
    {
        btnCerrar.IsEnabled = true;
    }

    public void Clear()
    {
        txtInner.Clear();
    }

    public void DesactivarCerrar()
    {
        btnCerrar.IsEnabled = false;
    }

    #endregion  
}

le code de la classe ConsoleView

static public class ConsoleView
{
    //DEFINICIONES DE LA CLASE
    #region DEFINICIONES DE LA CLASE
    static FrmConsole console;
    static Thread StatusThread;
    static bool isActive = false;
    #endregion

    //CONSTRUCTORES DE LA CLASE
    #region CONSTRUCTORES DE LA CLASE

    #endregion

    //PROPIEDADES
    #region PROPIEDADES

    #endregion

    //DELEGADOS
    #region DELEGADOS

    #endregion

    //METODOS Y FUNCIONES
    #region METODOS Y FUNCIONES

    public static void Show(string label)
    {
        if (isActive)
        {
            return;
        }

        isActive = true;
        //create the thread with its ThreadStart method
        StatusThread = new Thread(() =>
        {
            try
            {
                console = new FrmConsole(label);
                console.ShowDialog();
                //this call is needed so the thread remains open until the dispatcher is closed
                Dispatcher.Run();
            }
            catch (Exception)
            {
            }
        });

        //run the thread in STA mode to make it work correctly
        StatusThread.SetApartmentState(ApartmentState.STA);
        StatusThread.Priority = ThreadPriority.Normal;
        StatusThread.Start();

    }

    public static void Close()
    {
        isActive = false;
        if (console != null)
        {
            //need to use the dispatcher to call the Close method, because the window is created in another thread, and this method is called by the main thread
            console.Dispatcher.InvokeShutdown();
            console = null;
            StatusThread = null;
        }

        console = null;
    }

    public static void Release()
    {
        isActive = false;
        if (console != null)
        {
            console.Dispatcher.Invoke(console.ActivarCerrar);
        }

    }
    #endregion
}

J'espère que ce résultat est utile.

1
Emelias Alvarez

Découvrez ce post, a été très utile pour moi. Téléchargez l'exemple de code:

http://www.codeproject.com/Articles/335909/Embedding-a-Console-in-a-C-Application

0
Sam Wright