2009-09-07 72 views
32

tôi chạy ffmpeg như thế này:Cách lấy đầu ra của System.Diagnostics.Process?

System.Diagnostics.Process p = new System.Diagnostics.Process(); 
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); 
p.Start(); 
p.WaitForExit(); 

... nhưng vấn đề là giao diện điều khiển với ffmpeg bật lên và biến mất ngay lập tức, vì vậy tôi không thể nhận được bất kỳ thông tin phản hồi. Tôi thậm chí không biết liệu quy trình có chạy đúng hay không.

Vậy làm thế nào tôi có thể một trong hai:

  • Cho console để duy trì mở

  • Lấy trong C# gì console hiển thị

Trả lời

48

Những gì bạn cần làm là nắm bắt luồng Đầu ra Chuẩn:

p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.UseShellExecute = false; 
// instead of p.WaitForExit(), do 
string q = ""; 
while (! p.HasExited) { 
    q += p.StandardOutput.ReadToEnd(); 
} 

Bạn cũng có thể cần phải làm điều gì đó tương tự với StandardError. Sau đó bạn có thể làm những gì bạn muốn với q.

Nó là một chút khó tính, như tôi đã phát hiện trong one of my questions

Như Jon Skeet đã chỉ ra, nó không phải là thông minh hiệu suất-khôn ngoan để sử dụng dây nối như thế này; thay vào đó, bạn nên sử dụng một số: StringBuilder:

p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.UseShellExecute = false; 
// instead of p.WaitForExit(), do 
StringBuilder q = new StringBuilder(); 
while (! p.HasExited) { 
    q.Append(p.StandardOutput.ReadToEnd()); 
} 
string r = q.ToString(); 
+4

nội dung cơ bản phải, nhưng tôi sẽ không khuyên bạn nên xây dựng chuỗi như thế.Sử dụng một StringBuilder :) –

+0

cảm ơn, có vẻ tốt Tôi sẽ cố gắng rằng ngay bây giờ – marcgg

+1

thực sự có một lỗi: StandardOut chưa được chuyển hướng hoặc quá trình chưa bắt đầu. Tôi đang cố gắng tìm ra những gì đang xảy ra – marcgg

3

Tôi biết câu hỏi này cũ, nhưng tôi vẫn sẽ thêm vào câu hỏi này.

Nếu tất cả những gì bạn muốn làm là hiển thị đầu ra của quy trình dòng lệnh, và bạn đang sinh ra quy trình từ cửa sổ bảng điều khiển, bạn chỉ cần chuyển hướng đầu vào tiêu chuẩn (vâng, tôi biết có vẻ sai, nhưng công trinh).

Vì vậy:

System.Diagnostics.Process p = new System.Diagnostics.Process(); 
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); 
p.UseShellExecute = false; 
p.RedirectStandardInput = true; 
p.Start(); 
p.WaitForExit(); 

sẽ làm tốt.

+0

Bạn không thêm nhiều vào nó, bởi vì điều đó đã được đề cập trong câu trả lời được chấp nhận. –

+0

Không, không phải là –

+16

Tôi có say rượu hoặc tên của Michael Vasquez và, thực sự, hầu hết HTML xung quanh nhận xét của anh ấy đều bị ngược? –

4

Để có câu trả lời cụ thể hơn liên quan trực tiếp đến ffmpeg, chuyển lệnh "-report" vào ffmpeg sẽ làm cho nó kết xuất nhật ký vào thư mục hiện tại với nội dung được hiển thị trong quá trình hiển thị.

‘-report’

Dump full command line and console output to a file named program-YYYYMMDD-HHMMSS.log in the current directory. This file can be useful for bug reports. It also implies -loglevel verbose.

Note: setting the environment variable FFREPORT to any value has the same effect.

Từ FFMpeg Documentation.

17

Câu trả lời của Lucas có điều kiện chủng tộc: Nếu quá trình kết thúc nhanh, vòng lặp trong khi còn lại (hoặc không bao giờ được nhập) ngay cả khi có một số đầu ra còn lại, đó là bạn có thể bỏ lỡ một số dữ liệu. Để ngăn chặn điều đó, cần thực hiện ReadToEnd khác sau khi quy trình đã thoát.

(Lưu ý rằng so với các phiên bản cũ của câu trả lời của tôi, tôi không còn có thể nhìn thấy một nhu cầu cho WaitForExit lần cờ process.HasExited là đúng, vì vậy đây boils xuống :)

using (var process = Process.Start(startInfo)) 
{ 
    var standardOutput = new StringBuilder(); 

    // read chunk-wise while process is running. 
    while (!process.HasExited) 
    { 
     standardOutput.Append(process.StandardOutput.ReadToEnd()); 
    } 

    // make sure not to miss out on any remaindings. 
    standardOutput.Append(process.StandardOutput.ReadToEnd()); 

    // ... 
} 
+0

Tôi tin rằng ví dụ đầu tiên tạo ra tình huống bế tắc. Nếu quá trình viết quá nhiều đầu ra, nó sẽ chặn chờ cơ hội viết thêm đầu ra. Điều này sẽ không xảy ra cho đầu ra dưới một ngưỡng nhất định. Nếu nó bị chặn, nó sẽ bị treo mãi mãi. [Cho đến khi bị giết] – Cameron

+0

@Cameron - Tôi đã cập nhật câu trả lời và xóa đoạn mã đầu tiên. Hơn nữa, trong đoạn thứ hai, tôi không thể nhìn thấy một nhu cầu cho 'WaitToExit' nữa: Một khi vòng lặp while còn lại, nó có nghĩa là quá trình đã thoát. Tuy nhiên tôi không chắc chắn về yêu cầu của bạn. Điều đó có nghĩa là ngay cả trong một tình huống mà bạn không quan tâm đến đầu ra của quy trình, bạn sẽ luôn phải thêm một cấu trúc ReadToEnd trong khi ở đâu đó trong mã của bạn mà bạn muốn bắt đầu một quá trình bằng cách sử dụng 'Process.Start' như để đảm bảo quá trình không đứng yên trong "không gian trống". – chiccodoro

+0

Tôi đã xác minh khiếu nại của mình sau bài đăng. Kiểm tra nó và xem. – Cameron

Các vấn đề liên quan