Я пытаюсь создать оболочку cmd.exe, но я не могу понять, как дождаться завершения процесса в процессе cmd.
Когда im запускает ping.exe в моей программе, моя "строка ввода" (путь) будет выводиться на консоль до завершения команды ping.
Я не могу использовать:.WaitForInputIdle(); потому что у меня нет графического интерфейса. "Это может быть связано с тем, что процесс не имеет графического интерфейса".
Можно ли вообще решить или есть лучший способ сделать это?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ObjectTest
{
class cmd
{
Process cmdProcess;
StreamWriter cmdStreamWriter;
public cmd()
{
//WinAPI.ShowConsoleWindow();
Process();
//WinAPI.HideConsoleWindow();
}
private void Process()
{
StartCmd();
string command = "";
while (command != "exit")
{
Thread.Sleep(100);
cmdProcess.WaitForInputIdle();
Console.Write(Environment.NewLine + Directory.GetCurrentDirectory() + "> ");
command = Console.ReadLine();
SendCommand(command);
}
}
private void StartCmd()
{
cmdProcess = new Process();
cmdProcess.StartInfo.FileName = "cmd.exe";
cmdProcess.StartInfo.UseShellExecute = false;
cmdProcess.StartInfo.CreateNoWindow = true;
cmdProcess.StartInfo.RedirectStandardOutput = true;
cmdProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
cmdProcess.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler);
cmdProcess.StartInfo.RedirectStandardInput = true;
cmdProcess.Start();
cmdStreamWriter = cmdProcess.StandardInput;
cmdProcess.BeginOutputReadLine();
}
private void SendCommand(string command)
{
cmdStreamWriter.WriteLine(command);
}
private void btnQuit_Click(object sender, EventArgs e)
{
cmdStreamWriter.Close();
cmdProcess.WaitForExit();
cmdProcess.Close();
}
private static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data))
{
Console.WriteLine(outLine.Data);
}
}
}
}
При запуске процесса вы можете указать, что вы хотите подождать:
var process = Process.Start(...);
process.WaitForExit();
Здесь ссылка на MSDN объясняет это: http://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx
Я думаю, это вам нужно.
Если это только фактические процессы, которые вы хотите поймать, вы можете использовать методы опроса как таковые:
Перед запуском команды собрать все существующие процессы, например, ping
(.exe), используя Process.GetProcessesByName
и сохранить их PID.
Запустить команду
Чтобы ждать выхода, снова сканируйте все процессы ping
и подождите все процессы, которые ранее не существовали.
Обратите внимание, что это не сработает или, по крайней мере, не будет точным, если другой процесс запустит другой ping
между шагами 1 и 3.
Вы также должны помнить, что CMD
не ждет всех типов процессов, только те, которые определены как консольные приложения (см. Этот вопрос).