Если процесс не завершается принудительно, например, убивая его из диспетчера задач или используя Environment.FailFast, вы должны иметь возможность сделать что-то подобное в вашем методе Main:
public static void Main(string[] args) {
try {
DoNormalStartupStuff();
}
finally {
foreach (var process in _runningProcesses) {
process.Kill();
}
}
}
Другим вариантом является информирование дочерних процессов об их идентификаторе родительского процесса, либо путем передачи идентификатора процесса из родительского процесса в дочерний процесс, либо делает что-то подобное . Затем дочерний процесс может отслеживать родительский процесс и, если он завершается, дочерний процесс может совершить самоубийство.