1

I have an application that spawns multiples threads, one of which runs an iPerf executable which is used to monitor network reliability. This process will run indefinitely, until the user attempts to close the window. This is where the issue comes in. I am trying to shut that process down gracefully so that the iPerf server does not get hung up, but I can not seem to get this working. I can shut it down just fine if I run the command manually from a command prompt and press Ctrl+c, but this does not seem to be easily done programmatically.

I have tried multiple things, including process.Kill(); or process.StandardInput.Close() or even process.StandardInput.WriteLine("\x3"); but none of these seem to send a graceful shutdown message to the process. process.Kill(); causes the server to hang or fail to start up the next time, and the other two options do not stop the server at all. But the manual ctrl+c works just fine.

Here is a snippet of my code:

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();

Any help is greatly appreciated. Thank you!

UPDATE:

Based on the suggestion from Hans in the comment, I tried adding some stuff to the code to get the ctrl+c event sent over.

[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);
}

This did not work at all. The process is still running and it does the function added returns false. I did check that the process id being passed matches the id of the process in task manager. That all is fine, but the GenerateConsoleCtrlEvent function returns false. Any idea why this may be?

MZimmerman6
  • 8,445
  • 10
  • 40
  • 70
  • http://pinvoke.net/default.aspx/kernel32/GenerateConsoleCtrlEvent.html – Hans Passant Feb 18 '16 at 20:24
  • @HansPassant Thanks for the link. Maybe I am not understanding the link properly or implemented the code incorrectly, but I have updated my question accordingly above to show the code I added for this console event, and it does not seem to actually do anything. – MZimmerman6 Feb 18 '16 at 21:03
  • Do also note that I need to be able to access the output of this process as close to real time as possible. – MZimmerman6 Feb 18 '16 at 21:27

1 Answers1

0

BeginOutputReadLine

Link describes how to do exactly what you are looking for in the example.

Why not use the built in Exited event to wait on so you are not blocking? Especially if you are spawning multiple threads. If you want to block then WaitForExit() is available as well.

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!
}

If you close the standard input, how are you going to write/flush it?

After you have WaitForExit() you also need to Close()

  • I should have made it more clear that the lines here are not necessarily in that order, or even all in the code at once. Just showing things that I had tried. – MZimmerman6 Feb 18 '16 at 20:42
  • I am also not entirely sure you are understanding what I am asking. I need to gracefully shut down a process, to which i have a handle. If this process does not shutdown gracefully, it makes the server hang. – MZimmerman6 Feb 18 '16 at 21:30