Здається, я трохи запізнився з цим питанням, але все одно напишу щось для тих, хто має таку ж проблему. Це та сама відповідь, яку я дав на це запитання.
Моя проблема полягала в тому, що я хотів би, щоб моя програма була програмою графічного інтерфейсу, але виконувані процеси повинні виконуватися у фоновому режимі без будь-якого вікна інтерактивної консолі. Я думаю, що це рішення також має працювати, коли батьківський процес є консольним процесом. Можливо, вам доведеться видалити прапор "CREATE_NO_WINDOW".
Мені вдалося вирішити це за допомогою GenerateConsoleCtrlEvent () за допомогою програми-обгортки. Хитра частина полягає лише в тому, що документація насправді не зовсім зрозуміла, як саме її можна використовувати та підводні камені.
Моє рішення базується на тому, що описано тут . Але це насправді не пояснило всіх деталей і з помилкою, тому ось деталі про те, як змусити його працювати.
Створіть нову додаткову програму "Helper.exe". Ця програма розміщуватиметься між вашою програмою (батьківською) та дочірнім процесом, який ви хочете мати можливість закрити. Це також створить власне дочірній процес. У вас повинен бути цей процес "середньої людини", інакше GenerateConsoleCtrlEvent () не вдасться.
Використовуйте якийсь механізм IPC, щоб повідомляти від батьків до допоміжного процесу, що помічник повинен закрити дочірній процес. Коли помічник отримує цю подію, він викликає "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)", який закриває себе та дочірній процес. Я сам використовував для цього об’єкт події, який батько завершує, коли хоче скасувати дочірній процес.
Щоб створити свій Helper.exe, створіть його за допомогою CREATE_NO_WINDOW та CREATE_NEW_PROCESS_GROUP. І під час створення дочірнього процесу створіть його без прапорів (0), що означає, що він буде отримувати консоль від свого батька. Якщо цього не зробити, це призведе до ігнорування події.
Дуже важливо, щоб кожен крок робився таким чином. Я пробував всілякі різновиди комбінацій, але ця комбінація єдина, яка працює. Ви не можете надіслати подію CTRL_C. Це поверне успіх, але процес буде ігнорувати. CTRL_BREAK - це єдиний, який працює. Це насправді не має значення, оскільки в кінці вони обидва зателефонують до ExitProcess ().
Ви також не можете викликати GenerateConsoleCtrlEvent () з ідентифікованим груповим процесом ідентифікатором дочірнього процесу, що дозволяє допоміжному процесу продовжувати жити. Це теж не вдасться.
Я витратив цілий день, намагаючись це зробити. Це рішення працює для мене, але якщо хтось має щось ще додати, будь ласка. Я обходив всю мережу, знаходячи багато людей з подібними проблемами, але не маючи чіткого рішення проблеми. Принцип роботи GenerateConsoleCtrlEvent () також трохи дивний, тому, якщо хтось знає більше деталей про нього, будь ласка, поділіться ним.
jstack
може бути надійно використовуватися замість цього для цього конкретного питання: stackoverflow.com/a/47723393/603516