Я сделал следующий простой пример, который должен захватить весь вывод и отправить его на мой сервер, где он просто декодируется обратно в строку (сервер C #) и записывается на консоль с использованием Console.WriteLine()
:
var process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.UseShellExecute = false;
process.StartInfo.Arguments = "/C " + command;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (s, e) => {
if(e.Data == null)
return;
var bytes = Encoding.Default.GetBytes(e.Data);
client.Send(bytes, bytes.Length);
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
Чтобы проверить это, в качестве команды я использовал systeminfo
, которая отображает то, что в данный момент делает в первой строке (вероятно, используя \r
), а затем отображает все данные в несколько строк.Я проверил systeminfo
в CMD.Событие запускается только тогда, когда появляются все данные, что означает, что несколько секунд (когда пишется только первая консольная строка), я ничего не получаюПо сути, у меня нет никакого способа увидеть на сервере, что происходит.
Как я могу захватить буквально все?Мне также удалось использовать process.ErrorDataReceived
с активированным перенаправлением.У меня больше не было строк на клиентской консоли (в консоли появились правильные строки, но событие не было запущено), но триггер все еще не вызывается.Что я сделал не так?
РЕДАКТИРОВАТЬ (из-за возможного дубликата):
Я изменил код, чтобы использовать StandardOutput
:
process.Start();
Task.Run(() => {
var buf = new char[256];
int readed;
while(! process.HasExited) {
readed = process.StandardOutput.Read(buf, 0, 256);
var bytes = Encoding.Default.GetBytes(buf, 0, readed);
client.Send(bytes, bytes.Length);
}
});
Такое же поведение происходит, код достигает объявления bytes
в пределах while
, когда команда пишет нормальные строки, но пока она пишет в первой строке, ничего не происходит.Протестировал его также с StandardError
.
РЕДАКТИРОВАТЬ (что происходит на сервере):
while(true)
Console.WriteLine(Encoding.Default.GetString(server.Receive(ref client)));
Во всем вышеперечисленном я установил контрольные точки на .Send()
такЯ знаю, что отправляет клиент.