Обработка системных сообщений в консольной программе

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Обработка системных сообщений в консольной программе

Сообщение S_Gur » 30.06.2022 19:50:44

Господа, никто не сталкивался с подобной проблемой? Есть веб-сервер (основная идея взята отсюда https://wiki.lazarus.freepascal.org/fpWeb_Tutorial/ru). При запуске открывается консольное окно и мне надо управлять (в частности, на текущий момент) минимизацией и восстановлением этого окна. Хэндл я получил, сообщения посылаются нормально, но вот как и где их отловить, никак не могу найти. Подозреваю, что проблема эта того же порядка, что и проблема обработки закрытия этого окна (с помощью функции SetConsoleCtrlHandler), но уверенности нет... :|
S_Gur
постоялец
 
Сообщения: 120
Зарегистрирован: 30.12.2018 22:17:42

Re: Обработка системных сообщений в консольной программе

Сообщение Alex2013 » 01.07.2022 09:57:04

Сейчас мне немного в лом искать но на форуме есть куча информации по консольным приложениям .
https://clck.ru/rgEKf
https://clck.ru/rgE2e
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Обработка системных сообщений в консольной программе

Сообщение Shleps » 01.07.2022 11:13:17

S_Gur писал(а):Господа, никто не сталкивался с подобной проблемой? Есть веб-сервер (основная идея взята отсюда https://wiki.lazarus.freepascal.org/fpWeb_Tutorial/ru). При запуске открывается консольное окно и мне надо управлять (в частности, на текущий момент) минимизацией и восстановлением этого окна. Хэндл я получил, сообщения посылаются нормально, но вот как и где их отловить, никак не могу найти. Подозреваю, что проблема эта того же порядка, что и проблема обработки закрытия этого окна (с помощью функции SetConsoleCtrlHandler), но уверенности нет... :|

Вводные немного странные - как правило веб-сервера пишут лог не в консольное окно, а в файл. Теоретически можно заставить писать в поток (не тот, который фрипаскалевский, а тот который в Юниксе c | работает).

Если у вас веб-сервер консольный самописный, то он может писать лог в stdout или stderr чтобы администратор сам потом определял, куда его сохранять следующим макаром
webserver > log.txt &
webserver > log.txt 2>&1 & (для склейки stdout stderr в единый поток)
при этом вывод может быть отдан другой программе через конвейер
webserver | log-analyzer > log.txt &
а та программа может выполнять разумную обработку, записывать или куда-то пересылать. Например в стандартный rsyslog, который отошлет потом дальше в централизованные системы сбора логов предприятия. причем вам в своем приложении не придётся даже особо с этим возиться:
webserver | nc -u 127.0.0.1 514
Аватара пользователя
Shleps
постоялец
 
Сообщения: 194
Зарегистрирован: 14.06.2006 20:25:14

Re: Обработка системных сообщений в консольной программе

Сообщение S_Gur » 01.07.2022 11:26:57

Shleps, простите, мне сейчас абсолютно неважно, куда пишется лог. Проблема совсем не в этом. Веб-сервер запускается в обычном системном командном окне. Это окно можно минимизировать, максимизировать, перетащить, изменить размер или просто закрыть крестиком. Именно эти системные сообщения (Hide, Restore, Minimize и прочие) мне надо отловить и обработать. При том, что хендл приложения я достаю и могу сам отправить ему команду на минимизацию. Вопрос в том, как к консольному приложению прицепить обработчик этих сообщений. Я сейчас играюсь с примером, описанным по этой ссылке:

http://delphimaster.net/view/1-25748/all

Пока зарегистрировать обработчик для моего приложения у меня не получается, к сожалению
S_Gur
постоялец
 
Сообщения: 120
Зарегистрирован: 30.12.2018 22:17:42

Re: Обработка системных сообщений в консольной программе

Сообщение Seenkao » 01.07.2022 12:29:28

S_Gur писал(а):При том, что хендл приложения я достаю и могу сам отправить ему команду на минимизацию.

Желательно найти цикл самого приложения и запросы делать оттуда. А вообще для этого создавали хуки. В Delphi это было популярное решение.
Seenkao
энтузиаст
 
Сообщения: 502
Зарегистрирован: 01.04.2020 03:37:12

Re: Обработка системных сообщений в консольной программе

Сообщение Sharfik » 01.07.2022 13:05:16

Seenkao писал(а):Желательно найти цикл самого приложения и запросы делать оттуда. А вообще для этого создавали хуки. В Delphi это было популярное решение.

С консолью наверно не будет работать. У него не оконное приложение.
S_Gur писал(а):Shleps, простите, мне сейчас абсолютно неважно, куда пишется лог. Проблема совсем не в этом. Веб-сервер запускается в обычном системном командном окне. Это окно можно минимизировать, максимизировать, перетащить, изменить размер или просто закрыть крестиком. Именно эти системные сообщения (Hide, Restore, Minimize и прочие) мне надо отловить и обработать. При том, что хендл приложения я достаю и могу сам отправить ему команду на минимизацию. Вопрос в том, как к консольному приложению прицепить обработчик этих сообщений. Я сейчас играюсь с примером, описанным по этой ссылке:

Вообще странная задача. Ибо недолго оно работать будет. Не под каждой ОС, и до ближайшего обновления ОС. Пока кто то не решит что технология устарела и надо выпендрится.

https://delphicode.ru/publ/delphi/prim/ ... /4-1-0-116
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Re: Обработка системных сообщений в консольной программе

Сообщение Seenkao » 01.07.2022 13:10:47

Sharfik, на Linux возможно не будет. На Windows это обычное окно, потому события перехватываются.
Seenkao
энтузиаст
 
Сообщения: 502
Зарегистрирован: 01.04.2020 03:37:12

Re: Обработка системных сообщений в консольной программе

Сообщение Shleps » 01.07.2022 13:44:59

S_Gur писал(а):Проблема совсем не в этом. Веб-сервер запускается в обычном системном командном окне. Это окно можно минимизировать, максимизировать, перетащить, изменить размер или просто закрыть крестиком. Именно эти системные сообщения (Hide, Restore, Minimize и прочие) мне надо отловить и обработать. При том, что хендл приложения я достаю и могу сам отправить ему команду на минимизацию. Вопрос в том, как к консольному приложению прицепить обработчик этих сообщений. Я сейчас играюсь с примером, описанным по этой ссылке:


Так в том-то и дело, что если веб-сервер является консольным приложением, то он _не_запускается_в_ окне_. он запускается из шелла, который может быть в окне терминала. А может быть из шелла, не принадлежащего окну терминала вообще. (в случае операционной системы без графической оболочки или с доступом по ssh или в режиме сервиса)
сообщения (Hide, Restore, Minimize и прочие) направлены оконному менеджеру, а не приложению. и учитывая, что оконных менеджеров вагон и маленькая тележка, то это ещё и может быть реализовано по разному. В Gnome2 - metacity, в KDE - уже другой, но вроде все работают по DBUS, а в Astra Linux графическое окружение вообще своё, не похожее ни на GNOME, ни на KDE, ни на LXDE, ни на XFCE.

Добавлено спустя 10 минут 5 секунд:
Если же речь идет сугубо про Windows, то что будет делать консольный вебсервер если пользователь стартует его из оболочки типа FAR, запущенной в окне cmd или powershell (имеет право!)?
Веб-сервер запускается в обычном системном командном окне. Это окно можно минимизировать, максимизировать, перетащить,

это окно будет связано с Far'ом, а не с веб-сервером. Это все к тому, что выбранная архитектура всей системы и вытекающая из неё задача по перехвату сообщений - не совсем здоровые. ну никто так в индустрии не делает - ни апач, ни нгинкс, ни плон.
Аватара пользователя
Shleps
постоялец
 
Сообщения: 194
Зарегистрирован: 14.06.2006 20:25:14

Re: Обработка системных сообщений в консольной программе

Сообщение S_Gur » 01.07.2022 15:26:13

Seenkao писал(а):Linux возможно не будет. На Windows это обычное окно, потому события перехватываются.


Мне это и надо только для Windows. Задача, собственно, следующая - хочу это окошко минимизировать в трей. В проекте есть датамодуль, на нем сидит трейикон и прекрасно работает, иконка в трее создается. Получается, что у меня есть на текущий момент две задачи: при минимизации окна спрятать его из таскбара, а по щелчку на иконку в трее восстанавливать его. На самом деле это больше не необходимость, а эксперименты. Если программа запускается в фаре, то команды на принудительную минимизацию и восстановление будут просто игнорироваться, но обычное cmd-окно я прекрасно минимизирую, используя sendmessage. Просто хочется разобраться, можно ли такому окну обрабатывать сообщения, и если можно, то как... Меня шибко ломает, почему перехват закрытия окна разными способами, включая Ctrl+C у меня прекрасно работает, а как перехватывать системные сообщения - никак не могу найти
S_Gur
постоялец
 
Сообщения: 120
Зарегистрирован: 30.12.2018 22:17:42

Re: Обработка системных сообщений в консольной программе

Сообщение Shleps » 01.07.2022 16:58:42

S_Gur писал(а):Меня шибко ломает, почему перехват закрытия окна разными способами, включая Ctrl+C у меня прекрасно работает

Кстати неочевидно, что происходит при нажатии Ctrl+C. то ли приложению отдается сообщение о клавиатурном событии, то ли происходит аналог kill -15(или -9) <ProcessID>, инициированный процессом cmd. Если такое приложение будут снимать через диспетчер задач, то в трее тоже произойдет что-то непредсказуемое.
В общем-то комбинировать трей, который имеет место быть в графической сессии исключительно и службу/сервис, коим является веб-сервер, которые как правило работают в "безголовом" режиме (машины без мониторов, без графических сессий итд) - это тоже нездоровая идея. Если это какой-то совсем хитрый вебсервер, который например управляет железом или в чьи настройки надо влезать в графическом режиме по локоть для отладки - делают отдельное графическое приложение, которое общается с сервером по отдельному протоколу, и уже оно может иметь трееподобные функции. Так было с толстым клиентом VMWare GSX/ESX или MS IIS.
Аватара пользователя
Shleps
постоялец
 
Сообщения: 194
Зарегистрирован: 14.06.2006 20:25:14

Re: Обработка системных сообщений в консольной программе

Сообщение S_Gur » 01.07.2022 17:41:40

Shleps, в данном случае дело не в том, что конкретно происходит при нажатии Ctrl+C, а в том, что я прекрасно ловлю это событие. И никак не могу понять, как организовать ловлю других событий
S_Gur
постоялец
 
Сообщения: 120
Зарегистрирован: 30.12.2018 22:17:42

Re: Обработка системных сообщений в консольной программе

Сообщение Shleps » 01.07.2022 18:08:57

S_Gur писал(а):Shleps, в данном случае дело не в том, что конкретно происходит при нажатии Ctrl+C, а в том, что я прекрасно ловлю это событие. И никак не могу понять, как организовать ловлю других событий

Дело именно в этом. Если Ctrl-C порождает что-то наподобие UNIX-ного сигнала kill -9 - то у приложения нет и не было возможности его ловить. оно просто снимается с исполнения. как при убийстве из диспетчера задач кнопкой "удалить процесс".
В отличие от kill -15, где приложению говорят "закрывайся по хорошему: освобождай память, закрывай сокеты, файлы итд" и оно ещё может потрепыхаться
И поскольку подсистема "UNIX для Windows" (точнее POSIX) теперь стала нативной частью винды - отмахаться от архитектуры операционной системы, спрятавшись за своим компилятором теперь не удастся.
Аватара пользователя
Shleps
постоялец
 
Сообщения: 194
Зарегистрирован: 14.06.2006 20:25:14


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 41

Рейтинг@Mail.ru