Mặc dù thực tế rằng việc sử dụng GenerateConsoleCtrlEvent để gửi tín hiệu Ctrl + C là một câu trả lời đúng nó cần làm rõ ý nghĩa để làm cho nó làm việc trong khác nhau. Các loại ứng dụng NET.
Nếu ứng dụng NET của bạn không sử dụng giao diện điều khiển của riêng mình (WinForms/WPF/Windows Service/ASP.NET) dòng chảy cơ bản là:
- Gắn quá trình .NET chính để an ủi của quá trình bạn muốn Ctrl + C
- Ngăn chặn quá trình .NET chính từ dừng lại vì sự kiện Ctrl + C với SetConsoleCtrlHandler
- Tạo giao diện điều khiển sự kiện cho hiện console với GenerateConsoleCtrlEvent (processGroupId nên zero! trả lời với mã mà gửi p.SessionId sẽ không công việc và không chính xác)
- Ngắt kết nối từ giao diện điều khiển và khôi phục lại tổ hợp phím Ctrl + C xử lý theo quy trình chính
Đoạn mã sau minh họa làm thế nào để làm điều đó:
Process p;
if (AttachConsole((uint)p.Id)) {
SetConsoleCtrlHandler(null, true);
try {
if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT,0))
return false;
p.WaitForExit();
} finally {
FreeConsole();
SetConsoleCtrlHandler(null, false);
}
return true;
}
nơi SetConsoleCtrlHandler, FreeConsole, AttachConsole và GenerateConsoleCtrlEvent là phương pháp WinAPI mẹ đẻ:
internal const int CTRL_C_EVENT = 0;
[DllImport("kernel32.dll")]
internal static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(uint CtrlType);
Mọi thứ trở nên phức tạp hơn nếu bạn cần gửi Ctrl + C từ ứng dụng bảng điều khiển .NET. Phương pháp tiếp cận sẽ không hoạt động vì AttachConsole trả về false trong trường hợp này (ứng dụng bảng điều khiển chính đã có bảng điều khiển). Có thể gọi FreeConsole trước cuộc gọi AttachConsole nhưng kết quả là giao diện điều khiển ứng dụng .NET gốc sẽ bị mất và không thể chấp nhận được trong hầu hết các trường hợp.
Giải pháp của tôi đối với trường hợp này (mà thực sự làm việc và không có tác dụng phụ cho NET quá trình chính console):
- Tạo nhỏ chương trình điều khiển hỗ trợ .NET chấp nhận quá trình ID từ đối số dòng lệnh, thua nó giao diện điều khiển riêng với FreeConsole trước AttachConsole cuộc gọi và gửi Ctrl + C để quá trình với mã nêu trên
- chính NET quá trình giao diện điều khiển nhắm mục tiêu chỉ gọi tiện ích này trong tiến trình mới khi nó cần phải gửi Ctrl + C để một quá trình giao diện điều khiển
Nguồn
2015-03-26 08:48:58
Lưu ý rằng nó chỉ hoạt động nếu quá trình đang cố đọc từ đầu vào tiêu chuẩn. Đóng stdin không làm gì cho đến khi chương trình cố gắng đọc cái gì đó từ nó. – Doug
lý do tại sao nó hiển thị ngoại lệ này "StandardIn chưa được chuyển hướng." ? Tôi đang sử dụng ffmpeg để chụp màn hình – Ahmad