2010-09-04 13 views
11

Tại thời điểm này tôi đang bắt đầu một tập tin thực thi từ chương trình C# của tôi với:Chuyển hướng đầu ra (stdout, stderr) của một quá trình con ra cửa sổ Output trong Visual Studio

System.Diagnostics.Process.Start(@"DoSomeStuff.bat"); 

Những gì tôi muốn trở thành có thể làm là chuyển hướng đầu ra (stdout và stderr) của tiến trình con đó đến cửa sổ Output trong Visual Studio (cụ thể là Visual C# Express 2008).

Có cách nào để làm điều đó không?

(Ngoài ra:. Như vậy mà nó không phải tất cả đệm lên và sau đó nhổ ra đến cửa sổ Output khi quá trình con kết thúc)


(BTW: Tại thời điểm này tôi có thể nhận stdout (nhưng không stderr) của quy trình của phụ huynh xuất hiện trong cửa sổ Đầu ra, bằng cách đặt chương trình của tôi là "Ứng dụng Windows" thay vì "Ứng dụng giao diện điều khiển", điều này sẽ bị hỏng nếu chương trình chạy bên ngoài Visual Studio, nhưng điều này là ok trong trường hợp cụ thể của tôi .)

+0

Tất cả các phần đều có ở đây. Chuyển hướng đầu ra cho quá trình, sử dụng Trace để lấy nó trong cửa sổ Output. –

+0

Bạn đã tìm ra cách chuyển hướng đầu ra của một tiến trình con? Các câu trả lời được đưa ra dưới đây có thể chuyển hướng đầu ra của một quá trình cha mẹ nhưng không phải là một đứa trẻ. – Fiona

Trả lời

20
process.StartInfo.CreateNoWindow = true; 
process.StartInfo.UseShellExecute = false; 
process.StartInfo.RedirectStandardOutput = true; 
process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data); 
process.Start(); 
process.BeginOutputReadLine(); 

process.WaitForExit(); 

Cùng ý tưởng cho Error, chỉ cần thay thế Output trong những tên phương pháp/bất động sản.

+6

Câu trả lời này chủ yếu là đúng. Nó thiếu một số thứ. Cụ thể: 'Start' gọi trước' Begin ... ReadLine' và 'WaitForExit' sau đó. Cũng đặt 'RedirectStandardInput' thành true cố định một vấn đề gây ra bởi một trong các chương trình (cụ thể là plink) trong tập tin batch muốn có một stdin hợp lệ, mặc dù nó không sử dụng nó. –

+0

'WaitForExit()' có thể gây ra sự chờ đợi vô hạn. Luôn gọi phương thức với thời gian chờ: 'process.WaitForExit (10000)' => đợi 10 giây. –

-3

Bạn đã xem xét sử dụng một số DefaultTraceListener?

//Create and add a new default trace listener. 
    DefaultTraceListener defaultListener; 
    defaultListener = new DefaultTraceListener(); 
    Trace.Listeners.Add(defaultListener); 
+2

Điều này thậm chí không * từ xa * trả lời câu hỏi của tôi. Và từ trang MSDN được liên kết: "Một cá thể của lớp này được tự động thêm vào các bộ sưu tập Debug.Listeners và Trace.Listeners. Thêm một DefaultTraceListener thứ hai sẽ gây ra các thông báo trùng lặp trong cửa sổ đầu ra của trình gỡ lỗi và các hộp thông báo trùng lặp cho các xác nhận." câu trả lời của bạn tồi tệ hơn hoàn toàn vô dụng. –

+4

Revenge downvote, eh? Ở đẳng cấp, GenEric35. –

+0

+1 fo Giải thích về trang MSDN của Anderw – prabhakaran

2

Điều gì đang xảy ra ở đây là Visual Studio hiển thị đầu ra gỡ lỗi từ chương trình trong Cửa sổ đầu ra. Đó là: nếu bạn sử dụng Trace.WriteLine, nó sẽ xuất hiện trong Cửa sổ đầu ra, vì trình theo dõi mặc định. Bằng cách nào đó, ứng dụng Windows Form của bạn (khi nó sử dụng Console.WriteLine; Tôi giả sử bạn đang sử dụng Console.WriteLine) cũng viết đầu ra gỡ lỗi, và Visual Studio đang chọn cái này lên.

Nó sẽ không làm tương tự cho các quá trình con, trừ khi bạn nắm bắt rõ ràng đầu ra và chuyển hướng nó cùng với đầu ra của bạn.

+0

Về cơ bản đó là những gì tôi đang cố gắng hỏi - làm thế nào để bạn làm điều cuối cùng? (Và, tôi nhận ra tôi đã bỏ lỡ điều này từ câu hỏi của tôi: làm thế nào để làm điều đó "như nó xảy ra"?) –

8

Một biến thể của công trình này cho tôi - đăng bài này ngay bây giờ vì tôi muốn tôi tìm thấy nó trước đó. Lưu ý rằng đây chỉ là một đoạn trích được trích xuất từ ​​mã thực để có thể có lỗi nhỏ.

Kỹ thuật này dựa trên một số mã MSDN. Những gì tôi đã không thể tìm ra là làm thế nào để có được cửa sổ đầu ra để cập nhật "trên bay". Nó không cập nhật cho đến khi nhiệm vụ này trở lại.

// Set this to your output window Pane 
private EnvDTE.OutputWindowPane _OutputPane = null; 

// Methods to receive standard output and standard error 

private static void StandardOutputReceiver(object sendingProcess, DataReceivedEventArgs outLine) 
{ 
    // Receives the child process' standard output 
    if (! string.IsNullOrEmpty(outLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write(outLine.Data + Environment.NewLine); 
    } 
} 

private static void StandardErrorReceiver(object sendingProcess, DataReceivedEventArgs errLine) 
{ 
    // Receives the child process' standard error 
    if (! string.IsNullOrEmpty(errLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write("Error> " + errLine.Data + Environment.NewLine); 
    } 
} 

// main code fragment 
{ 
    // Start the new process 
    ProcessStartInfo startInfo = new ProcessStartInfo(PROGRAM.EXE); 
    startInfo.Arguments = COMMANDLINE; 
    startInfo.WorkingDirectory = srcDir; 
    startInfo.UseShellExecute = false; 
    startInfo.RedirectStandardOutput = true; 
    startInfo.RedirectStandardError = true; 
    startInfo.CreateNoWindow = true; 
    Process p = Process.Start(startInfo); 
    p.OutputDataReceived += new DataReceivedEventHandler(StandardOutputReceiver); 
    p.BeginOutputReadLine(); 
    p.ErrorDataReceived += new DataReceivedEventHandler(StandardErrorReceiver); 
    p.BeginErrorReadLine(); 
    bool completed = p.WaitForExit(20000); 
    if (!completed) 
    { 
     // do something here if it didn't finish in 20 seconds 
    } 
    p.Close(); 
} 
+0

Điều này sẽ không nhận được stdout và stderror theo thứ tự đúng .. – paulm

+0

@paulm bạn có ý nghĩa gì bởi nó sẽ không nhận được đúng thứ tự? Mã này không hoạt động đối với tôi khi chuyển hướng stderr (stdout đang hoạt động). Bất kỳ ý tưởng tại sao? – rboy

+0

Sử dụng câu trả lời từ câu hỏi của tôi - điều này sẽ không nhận được stderr và stdout theo thứ tự đúng, tức là nếu ứng dụng thực hiện, err, out, err bạn có thể nhận ra, ra, err, err vv – paulm