Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.05;
Скачать: CL | DM;

Вниз

Обработка сообщений в TService + TDataModule   Найти похожие ветки 

 
malefik   (2007-07-11 14:42) [40]

угу


 
clickmaker ©   (2007-07-11 14:49) [41]

может очередь сообщений не создается?
поставь
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
перед Wait...


 
Сергей М. ©   (2007-07-11 14:51) [42]

Пробуй так:

void __fastcall TSRVDozor::ServiceExecute(TService *Sender)
{
_start_srv();
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
PostThreadMessage(ServiceThread -> ThreadId, WM_CLIENT_LOG, 3, 5);
while (!Terminated)
{
 if (WaitMessage())
  {
      if(PeekMessage(&msg, -1 , WM_CLIENT_LOG, WM_CLIENT_LOG, PM_REMOVE) != 0)
      {
              _log_data_module->_write_to_log(msg.message,"asd",1,1);
      }
  ServiceThread->ProcessRequests(false);
  }
}
}


Сообщение наблюдаешь ?


 
Сергей М. ©   (2007-07-11 14:53) [43]


> может очередь сообщений не создается?


Создается.

Автор утверждает, что PostThreadMessage возвращает TRUE.


 
malefik   (2007-07-12 10:22) [44]

Короче вот такая картина....


void __fastcall TSRVDozor::ServiceExecute(TService* Sender)
{
_start_srv();
MSG msg;
_log_datamodule = new T_log_datamodule(this);
       _log_datamodule->_id_thread = GetCurrentThreadId();

PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
PostThreadMessage(_log_datamodule->_id_thread, WM_CLIENT_LOG, 0, 0);

while (!Terminated)
{
 if (WaitMessage())
 {
         Sleep(5);
  if (PeekMessage(&msg, NULL, WM_CLIENT_LOG, WM_CLIENT_LOG, PM_REMOVE) != 0)
  {
   _log_datamodule->_write_to_log(msg.message, "WM_CLIENT_LOG", 1, 1);
  }
  ServiceThread->ProcessRequests(false);
 }
}
delete _log_datamodule;
}



два таймера одновременно работают....один в дата модуле второй на модуле самого сервиса...

вот с таким кодом...


void __fastcall TSRVDozor::Timer1Timer(TObject *Sender)
{
_log_datamodule->_write_to_log(1, "SERVICE_TIMER", 1, 1);
//PostThreadMessage(_log_datamodule->_id_thread ,WM_CLIENT_LOG,0,0);
}

и в датамодуле


void __fastcall T_log_datamodule::_log_timerTimer(TObject* Sender)
{

_write_to_log(1, "LOG_TIMER", 1, 1);
PostThreadMessage(_id_thread ,WM_CLIENT_LOG,0,0);

//далее служебный код
if (FormatDateTime("hh:mm:ss", Time()) == "00:00:00")
{
 if (_ready)
 {
  _ready = false;
  FileClose(_file_handle);
  _prepare_log();
 }
}
}



смотрю сам лог файл.....


12:20:34|1|SERVICE_TIMER|1|1|
12:20:34|1|LOG_TIMER|1|1|
12:20:35|1|SERVICE_TIMER|1|1|
12:20:35|1|LOG_TIMER|1|1|
12:20:36|1|SERVICE_TIMER|1|1|
12:20:36|1|LOG_TIMER|1|1|
12:20:37|1|SERVICE_TIMER|1|1|
12:20:37|1|LOG_TIMER|1|1|
12:20:38|1|SERVICE_TIMER|1|1|
12:20:38|1|LOG_TIMER|1|1|
12:20:39|1|SERVICE_TIMER|1|1|
12:20:39|1|LOG_TIMER|1|1|
12:20:40|1|SERVICE_TIMER|1|1|
12:20:40|1|LOG_TIMER|1|1|
12:20:41|1|SERVICE_TIMER|1|1|
12:20:41|1|LOG_TIMER|1|1|
12:20:42|1|SERVICE_TIMER|1|1|
12:20:42|1|LOG_TIMER|1|1|


если делаю так


void __fastcall TSRVDozor::Timer1Timer(TObject *Sender)
{
_log_datamodule->_write_to_log(1, "SERVICE_TIMER", 1, 1);
PostThreadMessage(_log_datamodule->_id_thread ,WM_CLIENT_LOG,0,0);
}
........то

12:23:03|1|LOG_TIMER|1|1|
12:23:04|1|SERVICE_TIMER|1|1|
12:23:04|1044|WM_CLIENT_LOG|1|1|
12:23:04|1|LOG_TIMER|1|1|
12:23:05|1|SERVICE_TIMER|1|1|
12:23:05|1044|WM_CLIENT_LOG|1|1|
12:23:05|1|LOG_TIMER|1|1|
12:23:06|1|SERVICE_TIMER|1|1|
12:23:06|1044|WM_CLIENT_LOG|1|1|
12:23:06|1|LOG_TIMER|1|1|
12:23:07|1|SERVICE_TIMER|1|1|
12:23:07|1044|WM_CLIENT_LOG|1|1|
12:23:07|1|LOG_TIMER|1|1|
12:23:08|1|SERVICE_TIMER|1|1|
12:23:08|1044|WM_CLIENT_LOG|1|1|
12:23:08|1|LOG_TIMER|1|1|


СООБЩЕНИЕ ЛОВИТСЯ ......

ХОТЯ


void __fastcall T_log_datamodule::_log_timerTimer(TObject* Sender)
{

_write_to_log(1, "LOG_TIMER", 1, 1);

PostThreadMessage(_id_thread ,WM_CLIENT_LOG,0,0);


никуда не девался....


 
Сергей М. ©   (2007-07-12 10:37) [45]

Так.

Теперь выключи на время все свои таймеры и приведи содержимое лога для вот такого кода:

void __fastcall TSRVDozor::ServiceExecute(TService* Sender)
{
_start_srv();
MSG msg;
_log_datamodule = new T_log_datamodule(this);
      _log_datamodule->_id_thread = GetCurrentThreadId();

PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
PostThreadMessage(ServiceThread -> ThreadId, WM_CLIENT_LOG, 0, 0);

while (!Terminated)
{
if (WaitMessage())
{
 if (PeekMessage(&msg, NULL, WM_CLIENT_LOG, WM_CLIENT_LOG, PM_REMOVE) != 0)
 {
  _log_datamodule->_write_to_log(msg.message, "WM_CLIENT_LOG", 1, 1);
 }
 ServiceThread->ProcessRequests(false);
}
}
delete _log_datamodule;
}



 
ага   (2007-07-12 11:14) [46]

>Я надеюсь, трассировку своего сервиса ты осуществляешь по всем правилам отладки-трассировки сервисов под управлением встр.отладчика ?

угу


А нифига не угу. Твои сообщения из очереди ServiceThread->ProcessRequests забираить.
У тя таймер сработал - ты ушел в ProcessRequests. Тот вынул из очереди WM_TIMER и обработал, а енный обработчик добавил в очередь WM_CLIENT_LOG. ProcessRequests опять проверяет очередь - а вот он радимый, да тока куда ево девать не знаить. Ну и выбрасывает ево канечна.
Вывод - надоть окошко делать и ему слать, енто самое простое.


 
ага   (2007-07-12 11:21) [47]

Да, наверна надоть и про ето сказать, хе-хе:)

Когда на TService таймер кидашь, то ен в главном потоке создается, тудыть и WM_TIMER приходють и с ServiceThread->ProcessRequests енто дело не пересекаетьси


 
malefik   (2007-07-12 11:28) [48]


> Когда на TService таймер кидашь, то ен в главном потоке
> создается, тудыть и WM_TIMER приходють и с ServiceThread-
> >ProcessRequests енто дело не пересекаетьси
>


я вот тоже думал про разные треды......када поюзал сервис SPY++


 
Сергей М. ©   (2007-07-12 11:29) [49]


> ага   (12.07.07 11:14) [46]


> Ну и выбрасывает ево канечна


А это

12:23:03|1|LOG_TIMER|1|1|
12:23:04|1|SERVICE_TIMER|1|1|
12:23:04|1044|WM_CLIENT_LOG|1|1|

тогда откуда взялось, если "выбрасывает" ?

По-хорошему следует перекрыть DoCustomControl (на то он и есть виртуальный) и в его теле обрабатывать свои польз.сообщения. Правда, при этом возникают сложности с передачей параметров сообщения, но и это вполне решаемо.


 
malefik   (2007-07-12 11:31) [50]


> Теперь выключи на время все свои таймеры и приведи содержимое
> лога для вот


один раз

13:31:58|1044|WM_CLIENT_LOG|1|1|


 
Сергей М. ©   (2007-07-12 11:31) [51]


> Когда на TService таймер кидашь, то ен в главном потоке
> создается


Точно)
Я как-то упустил из вида этот крайне важный в дан.ситуации момент.


 
Сергей М. ©   (2007-07-12 11:32) [52]


> malefik   (12.07.07 11:31) [50]


Ну вот тебе и подтверждение [46] и [47]


 
ага   (2007-07-12 11:48) [53]

Ну да можна и DoCustomControl, я об ентом первым делом подумал:) Тока тады придетса WParam под код управления отдать, у нево типа как обе параметры испльзуить
PostThreadMessage(SRVDozor->_id_thread,WM_CLIENT_LOG,3,5);


 
malefik   (2007-07-12 11:55) [54]

по поводу 46 немного не догоняю.....

procedure TServiceThread.ProcessRequests(WaitForMessage: Boolean);
const
 ActionStr: array[1..5] of String = (SStop, SPause, SContinue, SInterrogate,
   SShutdown);
var
 msg: TMsg;
 OldStatus: TCurrentStatus;
 ErrorMsg: String;
 ActionOK, Rslt: Boolean;
begin
 while True do
 begin
   if Terminated and WaitForMessage then break;
   if WaitForMessage then
     Rslt := GetMessage(msg, 0, 0, 0)
   else
     Rslt := PeekMessage(msg, 0, 0, 0, PM_REMOVE);


Можно объяснить почему??

Каца я начинаю въезжать......после отлова WM_TIMER - таймер шлет мое сообщение которое перехватывает в еще не закончившемся круге
ServiceThread->ProcessRequests(false); обрабатывает его ......кодом ВЫШЕ...и я КУРЮ....НО ......

поток то я тот указывал ......для

void __fastcall T_log_datamodule::_log_timerTimer(TObject* Sender)
{

_write_to_log(1, "LOG_TIMER", 1, 1);
PostThreadMessage(_id_thread ,WM_CLIENT_LOG,0,0);



 
malefik   (2007-07-12 12:03) [55]

думаю что AllocateHWnd будет лучший выход


 
Сергей М. ©   (2007-07-12 12:25) [56]


> обрабатывает его ......кодом ВЫШЕ


..
   if msg.hwnd = 0 then { Thread message }
   begin
     if msg.message = CM_SERVICE_CONTROL_CODE then
     begin
..
     end else
       DispatchMessage(msg); <- вот здесь твое сообщение выкидывается нафих
   end else
     DispatchMessage(msg);


 
Сергей М. ©   (2007-07-12 12:28) [57]


> AllocateHWnd будет лучший выход


Но при этом ты будешь вынужден сделать сервис интерактивным (по умолчанию - False), иначе он не будет получать адресованные этому окну сообщения.


 
Сергей М. ©   (2007-07-12 12:30) [58]


> malefik   (12.07.07 12:03) [55]


Идеальное решение - обмен данными с сервисом при помощи NamedPipes.


 
malefik   (2007-07-12 12:55) [59]

Rslt := PeekMessage(msg, 0, 0, 0, PM_REMOVE);
тут оно удаляется из очереди.....чого бы я не очень хотел.....

> NamedPipes.

Как насчет безопасности???


 
ага   (2007-07-12 13:01) [60]

по поводу 46 немного не догоняю.....

Ну ты смотри. Пришел те WM_TIMER и ты попал в ProcessRequests. Че тот делает? Пока PeekMessge вертает истину он крутит цикл. Значить че происходит. Сначала вызывает обработчик WM_TIMER, тот добавит в очередь твой WM_CLIENT_LOG, дальше ProcessRequests пойдеть опять по циклу то бишь вызоветь PeekMessage, а тот найдеть в очереди WM_CLIENT_LOG ну и забереть ево оттедова. Секешь? Ну  а куды вон ево денет? Правильно Сергей сказал

if msg.message = CM_SERVICE_CONTROL_CODE then
begin
...
end else
   DispatchMessage(msg);

А куды ему ево отправлять ежли окно=0? Я б сказал да правила форума запрящають:) Ну да ты небось и сам знашь:))

>Но при этом ты будешь вынужден сделать сервис интерактивным

А нафига интерактивный-та? Ему ж не от юзера нать мессаги принимать, от свово ж потока. Дык усе потоки сервиса на одном десктопе вертятся и сообщения друг дружке и без интерактивности дайдуть. Тем боле ежли поток шлеть самому себе. Иль я чево опять не понял?:) Десктоп он вроде не меняет...


 
Сергей М. ©   (2007-07-12 13:03) [61]


> тут оно удаляется из очереди


Ну а как же иначе ?

Ведь если далее по коду будет принято решение о необходимости его обработки (или диспетчеризации по умолчанию), сообщение к этому моменту должно быть выбрано из очереди, а иначе его никак не "выковырять" - простое удаление сообщения из очереди (без его чтения при этом) системой не предусмотрено.


> Как насчет безопасности?


А что с ней не в порядке ?
Какие сомнения ?
И почему вопрос о какой-то там "безопасности" не возник у тебя при попытке организовать обмен посредством сообщений ?


 
Сергей М. ©   (2007-07-12 13:07) [62]


> Ему ж не от юзера нать мессаги принимать, от свово ж потока


Мне кажется, что таймер здесь был использован в кач-ве эксперимента.

А конечная цель - организация обмена данными с сервисом со стороны произвольного процесса.


 
ага   (2007-07-12 13:23) [63]

>А конечная цель - организация обмена данными с сервисом со стороны произвольного процесса.

А ну тады да. Тады канешна нать како-нить другой канал. И пайпы как раз в точку. Хотя и другие способы есть, но тут уж нать подробности задачи знать


 
malefik   (2007-07-12 14:02) [64]

Лана пасиба Камрады....буду ваять....



Страницы: 1 2 вся ветка

Текущий архив: 2007.08.05;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.03 c
1-1180122450
sniknik
2007-05-25 23:47
2007.08.05
Перебор терминальных сессий


15-1184093585
@!!ex
2007-07-10 22:53
2007.08.05
Что проиходит?


1-1180596738
ВременныйГость
2007-05-31 11:32
2007.08.05
MaskEdit


2-1184001195
Yurij-7
2007-07-09 21:13
2007.08.05
почему не работает запрос вида в FB ?


2-1184080030
bagos
2007-07-10 19:07
2007.08.05
n цифр после запятой