Текущий архив: 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