Я пытаюсь запустить процесс и захватить вывод, пришел далеко, но я не совсем в том решении, которое я бы хотел.
В частности, я пытаюсь использовать reset IIS на своей машине разработки из небольшого приложения-приложения, которое я пишу. Я пришел к выводу, экспериментируя, что безопасный способ сделать это - запустить iisreset.exe
в дочернем процессе.
Если вы запустите iisreset.exe
в командной строке, вы получите обратную связь во время процесса. Запуск iisreset занимает несколько секунд, и генерируется несколько строк обратной связи с паузами между ними.
Я хотел бы зафиксировать эту обратную связь и представить ее в своем приложении Windows Forms (в ListBox
), и мне это удалось. Моя оставшаяся забота заключается в том, что я не получаю ее до окончания процесса ребенка. Я хотел бы получить выход из дочернего процесса, по очереди, сразу же, когда строки создаются.
Я пытался сделать домашнее задание, читая/тестируя вещи, например. это:
- Как создать процесс и записать его STDOUT в .NET?
- Захват вывода консоли из приложения .NET(С#)
- http://www.aspcode.net/ProcessStart-and-redirect-standard-output.aspx
и еще несколько с похожим контентом. Большинство (все?) Получают выход асинхронно (например, с помощью Process.ReadToEnd()
). Я хочу синхронизировать вывод, который согласно документации MSDN включает в себя создание обработчика событий и т.д., И я пробовал это. Он работает, но обработчик события не вызывается, пока процесс не завершится. Я получаю вывод от iisreset.exe, но не до конца.
Чтобы исключить возможность того, что это имеет какое-то отношение к iisreset.exe, я написал небольшое консольное приложение, которое генерирует некоторый вывод, останавливаясь между ними:
namespace OutputGenerator
{
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("OutputGenerator starting and pausing for 10 seconds..");
System.Threading.Thread.Sleep(10000);
System.Console.WriteLine("Pausing for another 10 seconds..");
System.Threading.Thread.Sleep(10000);
System.Console.WriteLine("Exiting!");
}
}
}
Тестирование с этим оказывается, что я получаю захваченные данные, когда захочу. Таким образом, до некоторой степени кажется, что способ, которым iisreset.exe выводит данные, вступает в игру здесь.
Вот код программы (приложение Windows Forms), которая выполняет захват:
using System;
using System.Windows.Forms;
using System.Diagnostics;
namespace OutputCapturer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnRun_Click(object sender, EventArgs e)
{
// Running this will show all output after the process has exited
//String path = @"C:\Windows\system32\iisreset.exe";
// Running this will show all output "when it happens"
String path = @"C:\OutputGenerator.exe";
var p = new Process();
p.StartInfo.FileName = path;
p.StartInfo.UseShellExecute = false; // ShellExecute = true not allowed when output is redirected..
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += OutputDataReceived;
p.Start();
p.BeginOutputReadLine();
}
private delegate void OutputDataToTextboxDelegate(String s);
void OutputDataToTextbox(String s)
{
tbxOutput.Text += s + Environment.NewLine;
tbxOutput.Refresh();
}
private void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && e.Data.ToString() != "")
{
// Must run the update of the textbox in the same thread that created it..
tbxOutput.Invoke(
new OutputDataToTextboxDelegate(OutputDataToTextbox),
DateTime.Now.ToString() + ": " + e.Data.ToString()
);
}
}
}
}
Думая, что это была проблема с EOL-кодированием (вывод iisreset.exe
, представляющий собой одну строку для моего приложения)), я запустил сеанс отладки. Неа. Обработчик событий для StandardOutput
вызывается несколько раз (один раз для каждой выходной строки из iisreset.exe
), но эти вызовы поступают в один пакет после завершения процесса.
Я бы ЛЮБЛЮ, если бы смог получить результат от iisreset.exe
", когда это произойдет", чтобы я мог показать его как индикацию прогресса.
Я видел еще один поток с той же/подобной проблемой, Асинхронный захват с выхода процесса не работает должным образом, но без решения.
Я как бы тупой.