ฉันไม่แน่ใจว่าทำไมคุณไม่ต้องการเปลี่ยนเส้นทางไปยังไฟล์ มีสองวิธีที่ฉันจะให้ที่นี่ วิธีหนึ่งคือการเปลี่ยนเส้นทางและอ่านจากไฟล์อีกวิธีหนึ่งคือชุดของโปรแกรม
ท่อที่มีชื่อ
สิ่งที่ฉันทำคือเขียนสองโปรแกรมสำหรับ. NET 4. หนึ่งส่งออกไปยังไปป์ที่มีชื่ออื่น ๆ อ่านจากไปป์นี้และแสดงไปยังคอนโซล การใช้งานค่อนข้างง่าย:
asdf.exe | NamedPipeServer.exe "APipeName"
ในหน้าต่างคอนโซลอื่น:
NamedPipeClient.exe "APipeName"
น่าเสียดายที่สิ่งนี้สามารถเปลี่ยนเส้นทางstdout
(หรือstdin
รวมกัน) เท่านั้นไม่ใช่stderr
ด้วยตัวเองเนื่องจากข้อ จำกัด ในตัวดำเนินการไพพ์ ( |
) ในพรอมต์คำสั่งของ Windows หากคุณเข้าใจวิธีการส่งstderr
ผ่านผู้ปฏิบัติงานไปป์นั้นมันน่าจะใช้ได้ stderr
อีกทางเลือกหนึ่งเซิร์ฟเวอร์สามารถแก้ไขเพื่อเปิดโปรแกรมของคุณและโดยเฉพาะการเปลี่ยนเส้นทาง หากจำเป็นต้องแจ้งให้เราทราบในความคิดเห็น (หรือทำเอง); ไม่ยากเกินไปหากคุณมีความรู้เกี่ยวกับห้องสมุด C # และ. NET
คุณสามารถดาวน์โหลดเซิร์ฟเวอร์และไคลเอ็นต์
หากคุณปิดเซิร์ฟเวอร์หลังจากการเชื่อมต่อไคลเอนต์จะปิดทันที หากคุณปิดไคลเอนต์หลังจากการเชื่อมต่อเซิร์ฟเวอร์จะปิดทันทีที่คุณพยายามส่งบางอย่างผ่านมัน เป็นไปไม่ได้ที่จะเชื่อมต่อท่อที่ชำรุดอีกครั้งส่วนใหญ่เป็นเพราะฉันไม่สามารถทำสิ่งที่ซับซ้อนได้ในตอนนี้ นอกจากนี้ยัง จำกัด ให้ลูกค้าคนหนึ่งต่อเซิร์ฟเวอร์
รหัสแหล่งที่มา
สิ่งเหล่านี้เขียนด้วยภาษา C # มีจุดไม่มากที่พยายามอธิบาย พวกเขาใช้ .NET NamedPipeServerStreamและNamedPipeClientStream
เซิฟเวอร์:
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();
}
}
}
ลูกค้า:
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();
}
}
}
การเปลี่ยนเส้นทางไปยังไฟล์
type NUL>StdErr.temp
start powershell -c Get-Content StdErr.temp -Wait
MyExecutable.exe 2>StdErr.temp
- สร้างไฟล์ว่าง
- เริ่มหน้าต่างคอนโซลใหม่ที่ตรวจสอบไฟล์
- เรียกใช้ไฟล์เรียกทำงานและเปลี่ยนเส้นทาง
stderr
ไปยังไฟล์นั้น
นี้จะให้ผลที่ต้องการของหน้าต่างคอนโซลหนึ่งในการชมstdout
(และให้stdin
) stderr
และอีกครั้งเพื่อให้นาฬิกา
อะไรก็ตามที่เลียนแบบtail
จะใช้ได้ วิธี PowerShell ทำงานได้ตามปกติใน Windows แต่อาจช้าเล็กน้อย (เช่นมีความล่าช้าในการเขียนไฟล์และการแสดงไปยังหน้าจอ) ดูคำถาม StackOverflow นี้สำหรับtail
ทางเลือกอื่น
ปัญหาเดียวคือไฟล์ชั่วคราวอาจเติบโตค่อนข้างใหญ่ วิธีแก้ปัญหาที่เป็นไปได้คือการเรียกใช้ลูปที่พิมพ์เฉพาะในกรณีที่ไฟล์มีเนื้อหาและล้างไฟล์ทันทีหลังจากนั้น แต่จะทำให้เกิดสภาวะการแย่งชิง