10
votes

Contrôle de la cmd.exe de Winforms

Question: Je veux contrôler CMD.exe de Winforms.

Je ne veux pas dire chaque commande dans un seul processus, avec StarTupinfo, puis arrêtez-vous.

Je veux dire par exemple, démarrez l'invite de commande SQL ou GDB, envoyez la commande, recevoir une réponse, envoyez la commande suivante, recevez la réponse suivante, STOP SQL Command Invite
processus de sortie.

Fondamentalement, je veux écrire une interface graphique en plus de n'importe quelle application de console.

Je veux avoir la sortie de cmd.exe redirigé vers un champ de texte et l'entrée provenant d'un autre champ de texte (sur le bouton Appuyez sur le bouton Entrée / OK).

Je ne trouve pas d'échantillons pour cela. Y a-t-il un moyen?


0 commentaires

4 Réponses :


19
votes

Il y a un bel exemple sur codeProject

bonne chance!

-edit: Je pense que cela ressemble plus à cela, j'ai créé une forme simple, 2 textes de texte et trois boutons. La première zone de texte est pour la saisie de commande, la seconde (multiligne), affiche le résultat. P>

Le premier bouton exécute la commande, le deuxième bouton met à jour le résultat (car les résultats sont en lecture ASYNC) P>

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private static StringBuilder cmdOutput = null;
        Process cmdProcess;
        StreamWriter cmdStreamWriter;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cmdOutput = new StringBuilder("");
            cmdProcess = new Process();

            cmdProcess.StartInfo.FileName = "cmd.exe";
            cmdProcess.StartInfo.UseShellExecute = false;
            cmdProcess.StartInfo.CreateNoWindow = true;
            cmdProcess.StartInfo.RedirectStandardOutput = true;

            cmdProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
            cmdProcess.StartInfo.RedirectStandardInput = true;
            cmdProcess.Start();

            cmdStreamWriter = cmdProcess.StandardInput;
            cmdProcess.BeginOutputReadLine();
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            cmdStreamWriter.WriteLine(textBox2.Text);
        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            cmdStreamWriter.Close();
            cmdProcess.WaitForExit();
            cmdProcess.Close();
        }

        private void btnShowOutput_Click(object sender, EventArgs e)
        {
            textBox1.Text = cmdOutput.ToString();
        }

        private static void SortOutputHandler(object sendingProcess,
            DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                cmdOutput.Append(Environment.NewLine + outLine.Data);
            }
        }
    }
}


0 commentaires

2
votes

Vous n'avez pas besoin d'interoper pour cela. Le processus .NET La classe vous donne tout ce dont vous avez besoin, simplement rediriger le flux d'entrée standard et le flux de sortie standard et il est fait. Vous pouvez trouver de nombreux exemples comment faire cela sur Internet.


1 commentaires

Oui, mais ce n'est pas si simple si vous souhaitez émettre plusieurs commandes l'une après une autre dans le même processus, où la deuxième commande n'est pas connue au moment de la compilation, comme indiqué. Et pour cela, vous ne trouvez aucun qui fonctionne.



1
votes

Vous n'avez pas besoin d'utiliser cmd.exe pour cela, vous pouvez appeler les commandes directement avec processus.start () . Si vous redirect StandardInput et StandardOutPut, vous pouvez contrôler le processus.

J'ai écrit un exemple comme une réponse à une autre question .

éditer
Je n'ai pas un exemple complet pour cela, mais vous pourriez écouter StandardOutput avec le processus.outpuputDataReceiveedeceived événement Si vous ne voulez pas attendre de manière synchrone. Il existe un exemple sur la page MSDN.


2 commentaires

Cela ne résout en aucun cas le problème. Il ferme le flux d'entrée afin de lire la sortie, mais à partir de ce point, il n'est pas possible d'envoyer de nouvelles commandes.


@Quandary, j'ai mis à jour ma réponse avec un lien vers l'événement de sortieDataReced qui pourrait être plus utile dans votre cas.



0
votes

C'est la réponse parfaite: xxx

plus tôt sur j'ai essayé avec Wile OutputStream.peek ()! = -1 mais cela s'écrase par un bogue dans la fonction de pommeau .NET Framework Peeek, qui n'a pas eu de délai ou de lancer une erreur si vous lisez au-dessus de la fin du flux ...

Cela fonctionne mieux en ce qu'elle attrape vraiment Toute sortie, mais elle est loin d'être parfaite. xxx


0 commentaires