· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Послать CTRL_C_EVENT консольному приложению

. 1 . 2 . >>

Посл.отвђт Сообщен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 есть пример с переназначением стандартных ввода-вывода, но там оба приложения консольные…

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.057