У меня есть приложение, которое порождает несколько потоков, один из которых запускает iPerf
исполняемый файл, который используется для мониторинга надежности сети. Этот процесс будет выполняться бесконечно, пока пользователь не попытается закрыть окно. Вот где возникает проблема. Я пытаюсь корректно завершить этот процесс, чтобы сервер iPerf
не зависал, но я не могу заставить это работать. Я могу выключить его просто так, если я запустил команду вручную из командной строки и нажал Ctrl+c
, но это, похоже, нелегко сделать программно.
Я пробовал несколько вещей, в том числе process.Kill();
, process.StandardInput.Close()
или даже process.StandardInput.WriteLine("\x3");
, но ни один из них, похоже, не отправляет процессу постепенное завершение работы. process.Kill();
приводит к зависанию сервера или невозможности его запуска в следующий раз, а две другие опции вообще не останавливают сервер. Но мануал ctrl+c
работает нормально.
Вот фрагмент моего кода:
iperf_proc = new Process();
iperf_proc.StartInfo.FileName = Application.StartupPath + ".\\iperf3.exe";
String argumentStr = " -c " + test_data.host + " -t 0";
iperf_proc.StartInfo.Arguments = argumentStr;
iperf_proc.StartInfo.UseShellExecute = false;
iperf_proc.StartInfo.RedirectStandardOutput = true;
iperf_proc.StartInfo.RedirectStandardInput = true;
iperf_proc.StartInfo.RedirectStandardError = true;
iperf_proc.Start();
iperfRunning = true;
iperf_proc.BeginOutputReadLine();
iperf_proc.BeginErrorReadLine();
while (false == iperf_proc.HasExited)
{
if (true == processCancelled)
{
iperf_proc.StandardInput.Close(); // Doesn't Work!
iperf_proc.StandardInput.WriteLine("\x3"); // Doesn't Work!
iperf_proc.StandardInput.Flush(); // Doesn't Work!
}
}
iperf_proc.WaitForExit();
Любая помощь приветствуется. Спасибо!
ОБНОВЛЕНИЕ:
Основываясь на предложении Ханса в комментарии, я попытался добавить что-то в код, чтобы отправить событие ctrl+c
.
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
private enum CtrlEvents
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1
}
private void closeBtn_Click(object sender, EventArgs e)
{
processCancelled = true;
//iperf_proc.CloseMainWindow();
bool succeeded = GenerateConsoleCtrlEvent((uint)CtrlEvents.CTRL_C_EVENT, (uint)iperf_proc.Id);
}
Это вообще не сработало. Процесс все еще запущен, и добавленная функция возвращает false. Я проверил, что переданный идентификатор процесса соответствует идентификатору процесса в диспетчере задач. Все в порядке, но функция GenerateConsoleCtrlEvent возвращает false. Есть идеи, почему это может быть?