|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 14, 2004 17:23:24 Добрый день. Имеется консольное приложение, создаваемое через CreateProcess(CREATE_NEW_PROCESS_GROUP). Дескрипторы ввода-вывода переназначаются на анонимные пайпы. При некоторых условиях консольное приложение зацикливается и требуется послать ему Ctrl+C (оно умеет обрабатывать его). Попытка реализовать это через GenerateConsoleCtrlEvent(CTRL_C_EVENT,pInfo.dwProcessId) ни к чему не приводит: GetLastError возвращает 6 (неверный дескриптор). Как же всё-таки послать консольному приложению сигнал прерывания работы (Ctrl+C)?0 |
|
|
Дата: Авг 14, 2004 23:53:28 На CTRL_BREAK_EVENT тоже не реагирует ? |
|
|
Дата: Авг 15, 2004 07:23:18 Бляха-муха! Ну совсем народ на поиск забил! Ведь пару дней назад было. http://wasm.ru/forum/index.php?action=vthread&forum=4&topic=6737 |
|
|
Дата: Авг 15, 2004 12:11:55 Vladimir Bondarenko А ведь действительно, так не выходит. Если, например, взять tutorial Iczelion'a ("пайпы") и добавить в него запись — не получается завершить консольное приложение таким способом. bogrus Да, и на это не реагирует. Но не само приложение (например, tracert) не реагирует на Ctrl+C/Ctrl+Break, а не реагирует на GenerateConsoleCtrlEvent. Но почему код ошибки 6? Ведь даже если в dwGroupProcessID указать 0 (отсылать всем процессам, разделяющим консоль с моим), то всё одно ошибка та же. Toxic Что-то я в том топике не нашёл решения проблемы. Может, поделишься? |
|
|
Дата: Авг 15, 2004 18:57:24 · Поправил: Toxic sensy Надо в GenerateConsoleCtrlEvent вместо pID слать ноль, а у себя поставить handler, который будет глушить стандартный обработчик Ctrl+С дла вызывающего процесса(т.е. твоего). Да, и на это не реагирует. Но не само приложение (например, tracert) не реагирует на Ctrl+C/Ctrl+Break, а не реагирует на GenerateConsoleCtrlEvent Не надо ля-ля... Реагирует отлично. |
|
|
Дата: Авг 15, 2004 19:34:13 Toxic
SetConsoleCtrlHandler(NULL,TRUE);
.if !GenerateConsoleCtrlEvent(CTRL_C_EVENT,NULL){
DWORD r = GetLastError(); // результат 6
if!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,NULL){
r = GetLastError(); //результат 6
return NULL;
}
}
Или я неправильно ставлю обработчик? |
|
|
Дата: Авг 15, 2004 21:50:01 sensy Ох, а доки я за тебя читать буду? If the HandlerRoutine parameter is NULL, a TRUE value causes the calling process to ignore CTRL+C input, and a FALSE value restores normal processing of CTRL+C input. This attribute of ignoring or processing CTRL+C is inherited by child processes. Т.е. ты просто глушишь Ctrl+C для себя и всех своих порождений. Надо дать в SetConsoleCtrlHandler указатель на свою процедуру обработчика, и там возвращать True по приходе Ctrl+C, тем самым блокируя передачу сигнала следующему обработчику в цепочке(который вызывает ExitProcess). |
|
|
Дата: Авг 15, 2004 22:09:51 Toxic Хорошо, указал свой обработчик. Честно говоря, так сначала и собирался, но смутили слова который будет глушить стандартный обработчик, я подумал, что ignore Ctrl+C лучше. Но не в этом дело.
SetConsoleCtrlHandler(&Handler,TRUE);
…
if !GenerateConsoleCtrlEvent(CTRL_C_EVENT,NULL){
DWORD r = GetLastError(); // результат 6
if!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,NULL){
r = GetLastError(); //результат 6
return r;
}
return r;
}
1) Функции по прежнему возвращают код ошибки 6; 2) Управление в мой Handler так и не приходит. Можно пример кода рабочего? Или хотя бы объяснить, почему GetLastError = 6. |
|
|
Дата: Авг 15, 2004 23:26:21 sensy Дык непонятно, что ты запускаешь, как запускаешь и т.д. Я по вышеприведенной методике посылаю Ctrl+C на tracert - все сразу закрывается. Показывай свои СreateProcess и пайпы(если есть). _1113902227__tracert.jpg |
|
|
Дата: Авг 16, 2004 00:18:50 · Поправил: sensy Toxic Есть мысль. Многопоточность влияет на енто дело? Если пайпы создавать в одном потоке, а с приложением работать в другом?
SetConsoleCtrlHandler(&Handler,TRUE);
…
CreatePipe(&Pipes.hOutRead,&Pipes.hOutWrite,&SecAttrs,NULL);
CreatePipe(&Pipes.hInRead,&Pipes.hInWrite,&SecAttrs,NULL);
…
sInfo.dwFlags = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES;
sInfo.wShowWindow = SW_HIDE;
sInfo.hStdInput = Pipes.hInRead;
sInfo.hStdOutput = Pipes.hOutWrite;
sInfo.hStdError = Pipes.hOutWrite;
CreateProcess(NULL,szCmdBuf,&SecAttrs,&SecAttrs,TRUE,NULL,NULL,NULL,&sInfo,&pInfo);
…
CloseHandle(Pipes.hOutWrite);
CloseHandle(Pipes.hInRead);
…
// Break action
if !GenerateConsoleCtrlEvent(CTRL_C_EVENT,NULL){
DWORD r = GetLastError(); // результат 6
if!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,NULL){
r = GetLastError(); //результат 6
return r;
}
return r;
}
И tracert всё равно продолжает работать… |
|
|
Дата: Авг 16, 2004 00:24:03 А саму консоль ты создал? |
|
|
Дата: Авг 16, 2004 01:13:59 Toxic То есть? Работа с консолью - это дело подопытного приложения. Я же просто переназвачаю вход/выход его себе и всё. Или нет? Нужно и себе создавать консоль? Или как? |
|
|
Дата: Авг 16, 2004 01:23:28 AllocConsole CreatePipe SetStdHandle SetConsoleCtrlHandler CreateProcess GenerateConsoleCtrlEvent FreeConsole Читай MSDN: The GenerateConsoleCtrlEvent function sends a specified signal to a console process group that shares the console associated with the calling process. |
|
|
Дата: Авг 16, 2004 01:33:12 Я вот еще забавный случай вспомнил: дали мне оффлайновый форум какого-то дельфийского сайта. Там какой-то перец написал статью как с помощью пайпов и CreateProcess запустить консольное приложение и считать оттуда данные. И потом много отзывов было(и благодарности и критика), все серьезно обсуждали недостатки метода - когда консольная программа хочет получить от запустившео какие-либо дополнительные данные, то вся система виснет. И никто не обратил внимания, что в CreateProcess в hStdInput и hStdOutput переданы концы hRead и hWrite одного пайпа! |
|
|
Дата: Авг 16, 2004 09:26:33 Toxic AllocConsole SetStdHandle FreeConsole Даже если я — GUI-приложение? В MSDN есть пример с переназначением стандартных ввода-вывода, но там оба приложения консольные… |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.057 |