Форум: "Начинающим";
Текущий архив: 2010.11.21;
Скачать: [xml.tar.bz2];
ВнизService(служба) и Windows vista Найти похожие ветки
← →
alex.rus © (2010-08-25 09:06) [0]Здравствуйте.
Есть служба полностью работает на ХР, служба просто выводит сообщение, но под вистой не хочет работать, т.е. она запускается, в службах стоит статус что работает, но ни одного сообщения не выводит. галочка "Разрешить взаимодействие с рабочим столом" стоит. Запускал от разных пользователей и от локального админа и от админа домена. И устанавливал службу тоже от разных пользователей результат один и тот же.
← →
sniknik © (2010-08-25 09:24) [1]совместимость с XP в свойствах файла службы поставь. на висте она может и "просто выводит сообщение", но не на тот рабочий стол, сделай вместо него сохранение в файл, это же просто для проверки? в рабочей версии от сообщений лучше вообще отказаться.
← →
Anatoly Podgoretsky © (2010-08-25 10:13) [2]> alex.rus (25.08.2010 09:06:00) [0]
А что в логах?
← →
alex.rus © (2010-08-25 10:58) [3]Спасибо sniknik не знал что может выводиться сообщение не на тот раб. стол. А вот в файл все прекрасно выводиться. Сообщения я делал для проверки.
А вообще мне нужно поставить Ноок на перехват сообщений.
делаю так (В ХР работало):
hExe := GetModuleHandle(nil);
If (hExe <> 0) Then hExe := LoadLibrary(PChar(ParamStr(0)));
If (hExe = 0) Then Halt(0);
hHook := SetWindowsHookEx(13, @HookProc, hExe, 0);
While GetMessage(Msg, 0, 0, 0) Do
Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
If (hHook <> 0) Then UnhookWindowsHookEx(hHook);
В результате
hExe <> 0 и hHook<>0
Но до процедуры HookProc дело не доходит т.е. тело функции не выполняется
я вот думаю может в висту не утраивает в этой функции SetWindowsHookEx(13, @HookProc, hExe, 0); первый параметр ?
← →
Сергей М. © (2010-08-25 11:09) [4]
> Ноок на перехват сообщений
Каким боком к этому относится число "13" ?
> hExe := GetModuleHandle(nil);
> If (hExe <> 0) Then hExe := LoadLibrary(PChar(ParamStr(0)));
>
А это что за шаманство ?
> While GetMessage(Msg, 0, 0, 0) Do
> Begin
> TranslateMessage(Msg);
> DispatchMessage(Msg);
> End;
Это зачем ? Твоему сервису кто-то кроме SCM посылает сообщения что ли ? Тогда где и как ты их обрабатываешь ?
← →
Anatoly Podgoretsky © (2010-08-25 11:23) [5]> alex.rus (25.08.2010 10:58:03) [3]
sniknik знал!
← →
alex.rus © (2010-08-25 11:28) [6]Перехват сообщений от клавиатуры (нажатия клавиш имеется ввиду)
Вот это
Exe := GetModuleHandle(nil);
If (hExe <> 0) Then hExe := LoadLibrary(PChar(ParamStr(0)));
екзешник грузит сам себя как ДЛЛку ну чтоб обойтись без лишних ДЛЛ
ну а вот без этого
While GetMessage(Msg, 0, 0, 0) Do
Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
в ХР не работало
Сообщения обрабатывались SetWindowsHookEx(13, @HookProc, hExe, 0); функцией HookProc
← →
Сергей М. © (2010-08-25 11:35) [7]
> екзешник грузит сам себя как ДЛЛку ну чтоб обойтись без
> лишних ДЛЛ
>
Хук WH_KEYBOARD_LL = 13 не требует никаких DLL.
Убирай.
> без этого
> While GetMessage(Msg, 0, 0, 0) Do
> Begin
> TranslateMessage(Msg);
> DispatchMessage(Msg);
> End;
> в ХР не работало
И кто же твоему сервису, крутящемуся, как я полагаю, в доп.потоке, будет посылать WM_QUIT для выхода из этого цикла ?
← →
QAZ (2010-08-25 11:37) [8]ну вобщем шоб хватать клаву длл вобще не нужны
в висте и выше из сервиса это не прокатит полюбому ибо изолирован
← →
alex.rus © (2010-08-25 12:55) [9]чуть-чуть переписал
без этого:
Exe := GetModuleHandle(nil);
If (hExe <> 0) Then hExe := LoadLibrary(PChar(ParamStr(0)));
получилось так
const
WH_KEYBOARD_LL=13;
hHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0);
While GetMessage(Msg, 0, 0, 0) Do
Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
If (hHook <> 0) Then UnhookWindowsHookEx(hHook);
в ХР работает в висте нет
> И кто же твоему сервису, крутящемуся, как я полагаю, в доп.
> потоке, будет посылать WM_QUIT для выхода из этого цикла
> ?
А WM_QUIT никто не будет посылать, как службу остановят так все и остановиться.
Ну я знаю что это не правильно =) но пока так.
← →
Сергей М. © (2010-08-25 13:28) [10]
> WM_QUIT никто не будет посылать, как службу остановят так
> все и остановиться.
Зашибись логика.
Штатная остановка службы происходит по асинхронному командному сообщению SERVICE_CONTROL_STOP или SERVICE_CONTROL_SHUTDOWN, отправляемому сервис-менеджером сервису. Сервис получив это сообщение должен обработать его и отрапортовать сервис-менеджеру о своем останове.
Так вот в твоем коде в упор не видно ни ожидания ни обработки этих сообщений.
← →
alex.rus © (2010-08-25 13:52) [11]Ни это ли вы имеете ввиду? обработчик события когда сервис останавливается.
procedure TWHES.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
SThread.Terminate;
Stopped:=True;
end;
А Можно ли сделать так?
procedure TWHES.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
UnhookWindowsHookEx(hKeyHook);
SThread.Terminate;
Stopped:=True;
end;
Или вы имеете ввиду что нужно отдельно обрабатывать эти сообщения
← →
Сергей М. © (2010-08-25 14:22) [12]Меня сейчас интересует одно - где конкретно в коде твоего проекта фигурирует этот цикл с GetMessage
← →
alex.rus © (2010-08-25 14:33) [13]Вот этот кусок кода.
TServiceThread=class(TThread)
protected
procedure Execute; override;
end;
Procedure TServiceThread.Execute;
begin
hHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0);
While GetMessage(Msg, 0, 0, 0) Do
Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
If (hHook <> 0) Then UnhookWindowsHookEx(hHook);
end;
procedure TWHES.ServiceExecute(Sender: TService);
begin
while not Terminated do
ServiceThread.ProcessRequests(false);
end;
← →
Сергей М. © (2010-08-25 15:19) [14]Ну так вот я тебя и спрашиваю, к какого перепугу цикл с GetMessage в теле метода TServiceThread.Execute завершит свое выполнение, если никто и никогда этому потоку не посылает WM_QUIT ?
← →
Leonid Troyanovsky © (2010-08-25 21:40) [15]
> alex.rus © (25.08.10 11:28) [6]
> Перехват сообщений от клавиатуры (нажатия клавиш имеется
> ввиду)
И сервис клаву будет мять?
--
Regards, LVT.
← →
Юрий Зотов © (2010-08-26 01:17) [16]
> И сервис клаву будет мять?
Красивые имена...
← →
Anatoly Podgoretsky © (2010-08-26 07:07) [17]> Юрий Зотов (26.08.2010 01:17:16) [16]
Но что он с Клавой собирается делать, звучит красиво.
← →
alex.rus © (2010-08-26 07:23) [18]
> Сергей М. © (25.08.10 15:19) [14]
>
> Ну так вот я тебя и спрашиваю, к какого перепугу цикл с
> GetMessage в теле метода TServiceThread.Execute завершит
> свое выполнение, если никто и никогда этому потоку не посылает
> WM_QUIT ?
Ну например в ХР я не посылаю wm_quit никогда потому что, служба работать должна все время и останавливаться только по выключению компа, и почему то все работает все нажатия клавиш перехватываются.
Ну раз вы прицепились к этому сообщению wm_quit значит это имеет какое то значение. наверно в висте есть какой-то контроль за сервисами и надо всё таки посылать это сообщение. или может и нет никакого контроля просто хотите чтобы было все как положено. Точно скажите из-за этого не работает или нет?
← →
sniknik © (2010-08-26 08:03) [19]> чтобы было все как положено. Точно скажите из-за этого не работает или нет?
если найден глюк, его надо исправить, независимо от всего, и продолжать только после.
т.что "точно" тебя только "пошлют" как в службе поддержки если у клиента старая версия, и промежуточные исправляли какие то баги. независимо от того, что это были за баги и на, что жалобы. себе дороже разбирать "из-за этого это или не из-за этого".
т.что приведи код в порядок, к стандартному сервисному обработчику событий. и сам скажи "из-за этого не работает или нет".
← →
Anatoly Podgoretsky © (2010-08-26 09:32) [20]> sniknik (26.08.2010 08:03:19) [19]
Служба поддержки Микрософта не будет рассматривать заявку, если не
установлены все последние патчи, также поступают и другие.
← →
Сергей М. © (2010-08-26 09:37) [21]
> alex.rus © (26.08.10 07:23) [18]
> останавливаться только по выключению компа
Ну так она ж все равно останавливается не волшебным образом, а по получению SERVICE_CONTROL_STOP/SHUTDOWN. Получив это сообшение твоя служба возбудит событие OnStop, где ты вызываешь SThread.Terminate и ТУТ ЖЕ, т.е. не дождавшись фактического завершения потока TServiceThread, рапортуешь сервис-менеджеру о завершении работы своего сервиса установкой Stopped:=True.
А поток-то TServiceThread как работал, так и продолжает работать, вплоть до принудительного снятия его с выполнения и уничтожения системой !
Ибо WM_QUIT ему никто не посылает, а на флаг Terminated, который ты взводишь в вызове SThread.Terminate, ему плевать с высокой колокольни - он этот флаг не опрашивает.
Да и зачем вообще в этой задаче нужен еще один поток ?
Не нужен он здесь совсем. Ставь хук в OnStart и снимай в OnStop - этого вполне достаточно. Конечно же, при условии что указанная тобой хук-функция HookProc исполняется достаточно быстро.
← →
alex.rus © (2010-08-26 14:34) [22]
> Ставь хук в OnStart и снимай в OnStop
сделал так как вы посоветовали
procedure TWHES.ServiceStart(Sender: TService; var Started: Boolean);
begin
hHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0);
Started:=true;
end;
procedure TWHES.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
Stopped:=True;
end;
убрал цикл с GetMessage, все работает в ХР, а в висте нет
Если для проверки сделать так
procedure TWHES.ServiceStart(Sender: TService; var Started: Boolean);
begin
AssignFile(fs,"c:\txt.txt");
rewrite(fs);
writeln(fs,inttostr(hHook));
hHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0);
writeln(fs,inttostr(hHook));
Started:=true;
end;
то на диске С:\ просто создается пустой файл txt.txt
значит дело не доходит до hHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0); ?
← →
Anatoly Podgoretsky © (2010-08-26 14:37) [23]> alex.rus (26.08.2010 14:34:22) [22]
Вообще то дело не доходит до
writeln(fs,inttostr(hHook));
Но кто же пишет в голову диска?
← →
Сергей М. © (2010-08-26 14:38) [24]> дело не доходит до hHook
А файл кто будет закрывать, Пушкин ?
← →
alex.rus © (2010-08-26 15:45) [25]Не, файл у меня закрывался в TWHES.ServiceStop ошибка в другом была. Сейчас все пишет hHook=5113528
Но теперь не пишет в файл из функции HookProc видимо до туда дело не доходит теперь
Function HookProc(nCode: LongInt; wParam, lParam: LongInt): LongInt stdcall;
Var
.........
Begin
AssignFile(fs,"c:\txt1.txt");
rewrite(fs);
writeln(fs,"Hookproc");
CloseFile(fs);
If (nCode = HC_ACTION) And (wParam = WM_KEYUP) Then
Begin
.........
End;
Result := CallNextHookEx(hKeyHook, nCode, wParam, lParam);
End;
Может быть параметры функции не подходят, и надо уже другую функцию писать?
← →
Сергей М. © (2010-08-26 16:00) [26]
> видимо до туда дело не доходит
А из каких соображений ты вызываешь метод ProcessRequests именно с параметром False ?
← →
alex.rus © (2010-08-27 09:30) [27]Ну так как я пишу службу в первый раз, то для первого раза скопировал этот код с какого-то сайта, и особо я так не разбирался в этом, но я пробовал и с true и с false. Я так понял что если стоит true то сервис ждет сообщений от системы
SERVICE_CONTROL_STOP
SERVICE_CONTROL_PAUSE
SERVICE_CONTROL_CONTINUE
SERVICE_CONTROL_SHUTDOWN
SERVICE_CONTROL_INTERROGATE
ну а если false то он не будет ничего ждать а просто будет продолжать цикл
while not Terminated do
ServiceThread.ProcessRequests(false);
но вот что именно нужно ставить в моем случае я не знаю. Подскажите?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.11.21;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.004 c