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?