Nie jestem pewien, dlaczego nie chcesz przekierowywać do pliku. Istnieją dwie metody, które tutaj przedstawię. Jedną z metod jest przekierowanie do pliku i odczyt z niego, drugi to zestaw programów.
Nazwane rury
To, co zrobiłem, to napisanie dwóch programów dla .NET 4. Jeden wysyła wyjście do nazwanego potoku, drugi odczytuje z tego potoku i wyświetla na konsoli. Użycie jest bardzo proste:
asdf.exe | NamedPipeServer.exe "APipeName"
W innym oknie konsoli:
NamedPipeClient.exe "APipeName"
Niestety, może to tylko przekierować stdout
(lub stdin
połączyć), a nie stderr
samo, z powodu ograniczeń w operatorze potoku ( |
) w wierszu polecenia systemu Windows. Jeśli dowiesz się, jak wysłać stderr
za pośrednictwem tego operatora, powinien działać. Alternatywnie serwer można zmodyfikować, aby uruchomić program, a konkretnie przekierować stderr
. Jeśli to konieczne, daj mi znać w komentarzu (lub zrób to sam); nie jest to zbyt trudne, jeśli masz wiedzę o bibliotece „Proces” C # i .NET.
Możesz pobrać serwer i klienta .
Jeśli zamkniesz serwer po połączeniu, klient natychmiast się zamknie. Jeśli zamkniesz klienta po połączeniu, serwer zamknie się, gdy tylko spróbujesz coś przez niego wysłać. Ponowne podłączenie uszkodzonej rury nie jest możliwe, głównie dlatego, że nie mogę się teraz martwić robieniem czegoś tak skomplikowanego. Jest również ograniczona do jednego klienta na serwer .
Kod źródłowy
Są one napisane w C #. Nie ma sensu tego tłumaczyć. Korzystają z .NET NamedPipeServerStream i NamedPipeClientStream .
Serwer:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
namespace NamedPipeServer
{
class Program
{
static void Main(string[] args)
{
if (args == null || args.Length == 0)
{
Console.Error.WriteLine("[NamedPipeServer]: Need pipe name.");
return;
}
NamedPipeServerStream PipeServer = new NamedPipeServerStream(args[0], System.IO.Pipes.PipeDirection.Out);
PipeServer.WaitForConnection();
StreamWriter PipeWriter = new StreamWriter(PipeServer);
PipeWriter.AutoFlush = true;
string tempWrite;
while ((tempWrite = Console.ReadLine()) != null)
{
try
{
PipeWriter.WriteLine(tempWrite);
}
catch (IOException ex)
{
if (ex.Message == "Pipe is broken.")
{
Console.Error.WriteLine("[NamedPipeServer]: NamedPipeClient was closed, exiting");
return;
}
}
}
PipeWriter.Close();
PipeServer.Close();
}
}
}
Klient:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
namespace NamedPipeClient
{
class Program
{
static void Main(string[] args)
{
if (args == null || args.Length == 0)
{
Console.Error.WriteLine("[NamedPipeClient]: Need pipe name.");
return;
}
NamedPipeClientStream PipeClient = new NamedPipeClientStream(".", args[0], System.IO.Pipes.PipeDirection.In);
PipeClient.Connect();
StreamReader PipeReader = new StreamReader(PipeClient);
string tempRead;
while ((tempRead = PipeReader.ReadLine()) != null)
{
Console.WriteLine(tempRead);
}
PipeReader.Close();
PipeClient.Close();
}
}
}
Przekierowanie do pliku
type NUL>StdErr.temp
start powershell -c Get-Content StdErr.temp -Wait
MyExecutable.exe 2>StdErr.temp
- Utwórz pusty plik
- Uruchom nowe okno konsoli, które obserwuje plik
- Uruchom plik wykonywalny i przekieruj
stderr
dane wyjściowe do tego pliku
Zapewnia to pożądany efekt jednego okna konsoli do oglądania stdout
(i udostępniania stdin
), a drugiego do oglądania stderr
.
Wszystko, co naśladuje tail
, zadziałałoby. Metoda PowerShell działa natywnie w systemie Windows, ale może być nieco powolna (tzn. Istnieje pewne opóźnienie między zapisaniem pliku a wyświetleniem na ekranie). Zobacz to pytanie StackOverflow dla innych tail
alternatyw.
Jedynym problemem jest to, że plik tymczasowy może być dość duży. Możliwym obejściem jest uruchomienie pętli, która drukuje tylko wtedy, gdy plik ma zawartość i natychmiast wyczyści plik, ale spowoduje to sytuację wyścigu.