Tôi đoán là tôi hơi muộn với câu hỏi này nhưng dù sao thì tôi cũng sẽ viết một cái gì đó cho bất kỳ ai có cùng vấn đề. Đây là câu trả lời giống như tôi đã đưa ra cho câu hỏi này .
Vấn đề của tôi là tôi muốn ứng dụng của mình là một ứng dụng GUI nhưng các quy trình được thực thi phải chạy ở chế độ nền mà không có bất kỳ cửa sổ bảng điều khiển tương tác nào được đính kèm. Tôi nghĩ rằng giải pháp này cũng sẽ hoạt động khi quy trình mẹ là một quy trình bảng điều khiển. Tuy nhiên, bạn có thể phải xóa cờ "CREATE_NO_WINDOW".
Tôi đã quản lý để giải quyết vấn đề này bằng cách sử dụng GenerateConsoleCtrlEvent () với một ứng dụng trình bao bọc. Phần khó khăn chỉ là tài liệu không thực sự rõ ràng về cách chính xác nó có thể được sử dụng và những cạm bẫy với nó.
Giải pháp của tôi dựa trên những gì được mô tả ở đây . Nhưng điều đó cũng không thực sự giải thích tất cả các chi tiết và có lỗi, vì vậy đây là chi tiết về cách làm cho nó hoạt động.
Tạo một ứng dụng trợ giúp mới "Helper.exe". Ứng dụng này sẽ nằm giữa ứng dụng của bạn (cha mẹ) và quy trình con mà bạn muốn có thể đóng. Nó cũng sẽ tạo ra tiến trình con thực tế. Bạn phải có quy trình "người trung gian" này nếu không GenerateConsoleCtrlEvent () sẽ thất bại.
Sử dụng một số loại cơ chế IPC để giao tiếp từ cha mẹ đến quy trình trợ giúp mà người trợ giúp sẽ đóng quy trình con. Khi trình trợ giúp nhận được sự kiện này, nó gọi "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)" sẽ tự đóng và quy trình con. Tôi đã tự mình sử dụng một đối tượng sự kiện cho đối tượng này mà đối tượng phụ huynh hoàn thành khi nó muốn hủy tiến trình con.
Để tạo Helper.exe của bạn, hãy tạo nó với CREATE_NO_WINDOW và CREATE_NEW_PROCESS_GROUP. Và khi tạo tiến trình con, hãy tạo nó không có cờ (0) nghĩa là nó sẽ lấy giao diện điều khiển từ cha của nó. Không làm điều này sẽ khiến nó bỏ qua sự kiện.
Điều rất quan trọng là mỗi bước được thực hiện như thế này. Tôi đã thử tất cả các kiểu kết hợp khác nhau nhưng cách kết hợp này là cách duy nhất hoạt động. Bạn không thể gửi sự kiện CTRL_C. Nó sẽ trả lại thành công nhưng sẽ bị quá trình bỏ qua. CTRL_BREAK là công cụ duy nhất hoạt động. Không thực sự quan trọng vì cuối cùng cả hai đều sẽ gọi ExitProcess ().
Bạn cũng không thể gọi GenerateConsoleCtrlEvent () với id nhóm quy trình của id quy trình con trực tiếp cho phép quy trình trợ giúp tiếp tục hoạt động. Điều này cũng sẽ thất bại.
Tôi đã dành cả ngày để cố gắng làm việc này. Giải pháp này phù hợp với tôi nhưng nếu ai có bất kỳ điều gì khác để thêm, vui lòng làm. Tôi đã đi khắp mạng tìm kiếm rất nhiều người có vấn đề tương tự nhưng không có giải pháp chắc chắn cho vấn đề. Cách hoạt động của GenerateConsoleCtrlEvent () cũng hơi lạ nên nếu ai biết chi tiết hơn thì chia sẻ nhé.
jstack
có thể được tin cậy sử dụng thay cho vấn đề cụ thể này: stackoverflow.com/a/47723393/603516