2010-02-27 12 views
6

Wiem, że dla programu istnieje stdout/in/err i chcę przekierować wyjście programu do pliku zamiast wyjścia konsoli. I teraz ustalić to z poniższym kodzie:Jak napisać do strumienia StdOut programu bezpośrednio w C#?

FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate); 
StreamWriter sw = new StreamWriter(fs); 
TextWriter old = Console.Out; 
Console.SetOut(sw); 
Console.Write("bbb"); 
sw.Flush(); 

Ale takie podejście jest połączyć Programu stdout do Console.Out i przekierować Console.Out do pliku. To trochę tak:

Program.StdOut -> Console.Out -> File

Console.Out tutaj wydaje się być pomostem. Nie chcę tego mostu i nie chcę używać Console.Write(), aby uzyskać wyjście. Jak mogę mapować wyjściowy strumień programu do docelowego pliku bezpośrednio i napisać bezpośrednio na stdout programu zamiast na Console.Write()? Czego chcę to trochę tak:

Program.StdOut -> File

Process.StandardOutput nieruchomość tylko daje mi tylko do odczytu StreamReader obiekt. Jak napisać do Process.StandardOutput ?? Lub gdzie jest stdout programu stdout?

Wielkie dzięki.

Odpowiedz

6

można dorwać stdout aplikacji poprzez wywołanie Console.OpenStandardOutput. Stamtąd możesz robić, co chcesz, ze strumieniem, chociaż nie będziesz mógł go ponownie przypisać. Jeśli chcesz to zrobić, musisz P/Invoke SetStdHandle i samodzielnie zajmować się szczegółami.

EDIT: Dodano przykładowy kod dla P/Invoke trasę:

[DllImport("kernel32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool SetStdHandle(int nStdHandle, IntPtr nHandle); 

const int STD_OUTPUT_HANDLE = -11; 

static void RedirectStandardOutput(FileStream file) 
{ 
    SetStdHandle(STD_OUTPUT_HANDLE, file.SafeFileHandle.DangerousGetHandle()); 
} 
+0

Dzięki, MikeP. Zastanawiam się, dlaczego klasa Console mogłaby ubiegać się o metodę OpenStandardOutput(), dlaczego nie zaklasyfikować tej metody w klasie Process, myślę, że byłoby to bardziej uzasadnione. Jaka jest filozofia projektowania? – smwikipedia

+0

Nie wiem, dlaczego wybrali tę metodę. – MikeP

1

użyć klas ProcessStartInfo i Process i ustawić dla parametru RedirectStandardOutput wartość true, a następnie przechwycić dane wyjściowe ze strumienia.

ProcessStartInfo info = new ProcessStartInfo("process.exe", "-arg1 -arg2"); 
info.RedirectStandardOutput = true; 
Process p = Process.Start(info); 
p.Start(); 
string output = p.StandardOutput.ReadToEnd(); 
+1

Dzięki, Jake. Chcę wiedzieć, że w process.exe, jak pisać na standardowe wyjście programu? Jaki rodzaj kodu to zaimplementuje? Czy nadal jest to Console.Write()? Czy istnieje sposób, aby nie używać tej metody i pisać bezpośrednio na wyjściu programu? – smwikipedia

+0

Należy wyprowadzić wyjście programu zarówno do StdOut, jak i do drugiego strumienia.Jednym ze sposobów jest napisanie pętli wywołującej 'ReadToEnd()', zapisanie na obu wyjściach, następnie przespanie się, powtarzanie aż do zamknięcia strumienia. – spoulson

+0

Ustaw "info.UseShellExecute = false' i' p.StanardInput.Write() ', aby wysłać dane do procesu. Jeśli proces odbija dane, jesteś dobry, ale nie możesz po prostu przejąć procesu i użyć jego uchwytu StandardOutput jako własnego. – Jake

6

Prawdopodobnie nie należy ustawić stdout własnego procesu. Powodem, dla którego jest to stdout, jest to, że osoba dzwoniąca (linia poleceń, cokolwiek) może przekierować ją w dowolnym miejscu, bez konieczności znajomości programu.

To działa jak "typ foo.txt | więcej". Jeśli polecenie typu poczułoby, że można swobodnie redefiniować standardowe wyjście do pliku, to w ogóle by nie działało.

Jeśli chcesz pisać do strumienia, po prostu otwórz strumień i napisz do niego.

Powiązane problemy