Umlenken Konsolausgabe zu Textbox in separatem Programm
Frage
Ich entwickle eine Windows Forms-Anwendung, die mich erfordert ein eigenes Programm zu nennen, eine Aufgabe auszuführen. Das Programm ist eine Konsolenanwendung, und ich muß ein TextBox in meinem Programm der Standardausgabe von der Konsole umleiten.
Ich habe kein Problem, das Programm aus meiner Anwendung ausgeführt wird, aber ich weiß nicht, wie die Ausgabe in meine Anwendung zu umleiten. Ich brauche Ausgang zu erfassen, während das Programm mit Veranstaltungen läuft.
Das Konsolenprogramm wird nicht aufhören soll laufen, bis meine Anwendung beendet und der Text ändert sich ständig in unregelmäßigen Abständen. Was ich versuche, einfach zu tun, wird die Ausgabe von der Konsole einhaken einen Event-Handler auszulösen, die dann verwendet werden können, die TextBox zu aktualisieren.
Ich bin mit C # dem Programm und mit dem .NET-Framework für die Entwicklung zu codieren. Die ursprüngliche Anwendung ist kein .NET Programm.
EDIT: Hier ist Beispielcode von dem, was ich zu tun werde versuchen. In meinem letzten app, werde ich Console.WriteLine mit Code ersetzen Sie die TextBox zu aktualisieren. Ich habe versucht, einen Haltepunkt in meinen Event-Handler zu setzen, und es ist nicht einmal erreicht.
void Method()
{
var p = new Process();
var path = @"C:\ConsoleApp.exe";
p.StartInfo.FileName = path;
p.StartInfo.UseShellExecute = false;
p.OutputDataReceived += p_OutputDataReceived;
p.Start();
}
static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(">>> {0}", e.Data);
}
Lösung
Dies funktioniert für mich:
void RunWithRedirect(string cmdPath)
{
var proc = new Process();
proc.StartInfo.FileName = cmdPath;
// set up output redirection
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.EnableRaisingEvents = true;
proc.StartInfo.CreateNoWindow = true;
// see below for output handler
proc.ErrorDataReceived += proc_DataReceived;
proc.OutputDataReceived += proc_DataReceived;
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
// output will be in string e.Data
}
Andere Tipps
Sie können den folgenden Code verwenden
MemoryStream mem = new MemoryStream(1000);
StreamWriter writer = new StreamWriter(mem);
Console.SetOut(writer);
Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
assembly.EntryPoint.Invoke(null, null);
writer.Close();
string s = Encoding.Default.GetString(mem.ToArray());
mem.Close();
Ich habe eine Reihe von Hilfsmethoden zum O2 Platform (Open-Source-Projekt) hinzugefügt, die Sie leicht Skript ein erlauben Interaktion mit einem anderen Prozeß über die Konsole Ausgang und Eingang (siehe http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs )
Auch nützlich für Sie die API sein könnte, der die Betrachtung der Konsolenausgabe des aktuellen Prozesses ermöglicht (in einer vorhandenen Steuerung oder Popup-Fenster). Sehen Sie dieses Blog-Post für weitere Informationen:
Dank Marc Maxham für seine Antwort, die mich retten Zeit! Als Jon aller Klassen bemerkt, Hier ist meine Modifikation des Codes, wo UseShellExecute
muß, um auf false gesetzt werden, um zu umleiten IO-Streams, da sonst der Start()
Anruf ein InvalidOperationException
wirft. txtOut
ist eine WPF Nur-Lese-Textbox void RunWithRedirect(string cmdargs)
{
var proc = new Process()
{
StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
},
EnableRaisingEvents = true
};
// see below for output handler
proc.ErrorDataReceived += proc_DataReceived;
proc.OutputDataReceived += proc_DataReceived;
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}