From my program I need to run an external console program in the background:
p = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = "someConsoleApplication.exe",
Arguments = "someArguments",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
}
};
p.Start();
It works. The program runs in the background, does its work and then exits. But in some cases I need to stop the program when it's running. And here's the problem. If I do
p.Kill();
the program exits without saving data. So I need some way to "ask" program to exit, not to kill it. When I run it without "CreateNoWindow", it exits correctly if I close the window or press Ctrl+C. I've tried to send Ctrl+C message directly to the program when it's in the background mode (using Windows API), but it seems that programs can't process such messages when they have no window.
I also have found one not very good way to do so:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GenerateConsoleCtrlEvent(ConsoleCtrlEvent sigevent, int dwProcessGroupId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
public enum ConsoleCtrlEvent
{
CTRL_C = 0,
CTRL_BREAK = 1,
CTRL_CLOSE = 2,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN = 6
}
private void CrackingProcessCleanKill()
{
if (AttachConsole((uint)p.Id))
{
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, 0);
FreeConsole();
SetConsoleCtrlHandler(null, false);
}
}
But sometimes it unpredictably causes the whole application to close, not just the process p. It's also not a good solution, because that code can't be used in unit tests (or maybe it's my mistake?). I mean it works when used from a real application and throws exceptions when used from unit test.
So, what's the right way to do what I want?