No estoy seguro de por qué no desea redirigir a un archivo. Hay dos métodos que proporcionaré aquí. Un método es redirigir y leer desde un archivo, el otro es un conjunto de programas.
Tubos con nombre
Lo que hice fue escribir dos programas para .NET 4. Uno envía la salida a una tubería con nombre, el otro lee de esta tubería y se muestra en la consola. El uso es bastante simple:
asdf.exe | NamedPipeServer.exe "APipeName"
En otra ventana de consola:
NamedPipeClient.exe "APipeName"
Desafortunadamente, esto solo puede redirigir stdout
(o stdin
combinarse), no stderr
por sí solo, debido a limitaciones en el operador de canalización ( |
) en el Símbolo del sistema de Windows. Si descubre cómo enviar a stderr
través de ese operador de tubería, debería funcionar. Alternativamente, el servidor podría modificarse para iniciar su programa y redirigir específicamente stderr
. Si eso es necesario, hágamelo saber en un comentario (o hágalo usted mismo); no es demasiado difícil si tiene algún conocimiento de la biblioteca "Proceso" de C # y .NET.
Puede descargar el servidor y el cliente .
Si cierra el servidor después de la conexión, el cliente se cerrará inmediatamente. Si cierra el cliente después de la conexión, el servidor se cerrará tan pronto como intente enviar algo a través de él. No es posible volver a conectar una tubería rota, principalmente porque no me molesto en hacer algo tan complicado en este momento. También está limitado a un cliente por servidor .
Código fuente
Estos están escritos en C #. No tiene mucho sentido tratar de explicarlo. Usan .NET NamedPipeServerStream y NamedPipeClientStream .
El servidor:
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();
}
}
}
El cliente:
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();
}
}
}
Redireccionando a un archivo
type NUL>StdErr.temp
start powershell -c Get-Content StdErr.temp -Wait
MyExecutable.exe 2>StdErr.temp
- Crea un archivo vacío
- Inicie una nueva ventana de consola que vea el archivo
- Ejecute el ejecutable y redirija la
stderr
salida a ese archivo
Esto proporciona el efecto deseado de una ventana de consola para mirar stdout
(y proporcionar stdin
), y otra para mirar stderr
.
Cualquier cosa que imite tail
funcionaría. El método PowerShell funciona de forma nativa en Windows, pero puede ser un poco lento (es decir, hay cierta latencia entre la escritura en el archivo y la visualización en la pantalla). Vea esta pregunta de StackOverflow para otras tail
alternativas.
El único problema es que el archivo temporal puede crecer bastante. Una posible solución es ejecutar un bucle que solo se imprime si el archivo tiene contenido y borrar el archivo inmediatamente después, pero eso provocaría una condición de carrera.