Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.11.17;
Скачать: [xml.tar.bz2];

Вниз

Сервис в Win2K   Найти похожие ветки 

 
lds   (2003-10-23 11:07) [0]

Как на API написать сервис, ясенно не используя компонент TService?


 
Polevi   (2003-10-23 11:27) [1]

program someservice;

{$APPTYPE CONSOLE}

uses
SysUtils,
Windows,
WinSvc;

const
FServiceName:string="Some service";

var
FStatusHandle:THandle;
T:TSomeThread;
FLastStatus:DWORD;

procedure SetStatus(AStatus:DWORD);
var
st:TServiceStatus;
begin
st.dwServiceType:=SERVICE_WIN32_OWN_PROCESS;
st.dwCurrentState:=AStatus;
st.dwControlsAccepted:=SERVICE_ACCEPT_STOP;
st.dwWin32ExitCode:=NO_ERROR;
st.dwServiceSpecificExitCode:=0;
if (AStatus=SERVICE_START_PENDING) or (AStatus=SERVICE_STOP_PENDING) then
begin
st.dwCheckPoint:=1;
st.dwWaitHint:=1000;
end
else
begin
st.dwCheckPoint:=0;
st.dwWaitHint:=0;
end;
FLastStatus:=AStatus;
SetServiceStatus(FStatusHandle,st);
end;

procedure ServiceHandler(CtrlCode: DWord); stdcall;
begin
if CtrlCode=(SERVICE_CONTROL_STOP) then
begin
SetStatus(SERVICE_STOP_PENDING);
T.Stop;
end
else
SetStatus(FLastStatus);
end;

procedure ServiceMain(Argc: DWord; Argv: PLPSTR); stdcall;
begin
FStatusHandle:=RegisterServiceCtrlHandler(PChar(FServiceName),@ServiceHandler);
if (FStatusHandle <> 0) then
begin
try
SetStatus(SERVICE_RUNNING);
T:=TSomeThread.Create(false);
T.WaitFor;
finally
SetStatus(SERVICE_STOPPED);
end;
end;
end;

function InstallService:boolean;
var
scm,serv:THandle;
begin
scm:=OpenSCManager(nil,nil,SC_MANAGER_CREATE_SERVICE);
serv:=CreateService(scm,PChar(FServiceName),PChar(FServiceName),SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,
PChar(ParamStr(0)),nil,nil,nil,nil,nil);
Result:=serv<>0;
if Result then CloseServiceHandle(serv);
end;

procedure RemoveService;
var
scm,serv:THandle;
begin
scm:=OpenSCManager(nil,nil,SC_MANAGER_CONNECT);
serv:=OpenService(scm,PChar(FServiceName),SERVICE_ALL_ACCESS);
try
DeleteService(serv);
finally
CloseServiceHandle(serv);
end;
end;

var
ste:TServiceTableEntry;
s:string;
begin
{ TODO -oUser -cConsole Main : Insert code here }
if FindCmdLineSwitch("INSTALL",["-","\","/"], True) then
InstallService
else
if FindCmdLineSwitch("UNINSTALL",["-","\","/"], True) then
RemoveService
else
begin
ste.lpServiceName:=PChar(FServiceName);
ste.lpServiceProc:=@ServiceMain;
StartServiceCtrlDispatcher(ste);
end;
end.


 
lds   (2003-10-27 07:11) [2]

Чего-то не хочет он запускаться... Пишет, что функция не возвратила результата...


 
Юрий Зотов   (2003-10-27 14:32) [3]

var
ste: array[0..1] of TServiceTableEntry;

ste[0].lpServiceName:=PChar(FServiceName);
ste[0].lpServiceProc:=@ServiceMain;
ste[1].lpServiceName:=nil;
ste[1].lpServiceProc:=nil;

StartServiceCtrlDispatcher( ste[0]);

В процедуре ServiceHandler нужно обрабатывать, как минимум, коды SERVICE_CONTROL_STOP, SERVICE_CONTROL_SHUTDOWN (завершая сервис) и SERVICE_CONTROL_INTERROGATE (выдавая текущее состояние сервиса).

Кое-что по сабжу можно найти здесь:
http://borland.xportal.ru/index.php

А еще лучше - найти книгу:
Дж. Рихтер, Дж. Кларк. Программирование серверных приложений для Windows 2000.
Там разъясняется все, и подробно.


 
sniknik   (2003-10-27 15:06) [4]

точно рабочий
http://delphi.chertenok.ru/forum/my_download.php?tema=del&action=show&id=173


 
Polevi   (2003-10-27 15:17) [5]

>Юрий Зотов © (27.10.03 14:32) [3]
пример работает 100%


 
Юрий Зотов   (2003-10-27 15:36) [6]

> Polevi © (27.10.03 15:17) [5]

Я тоже пытался так делать. Не работало, пока не сделал массив с пустым последним элементом. Сразу же все стало ОК. То же самое сказано и в MSDN, и у Рихтера.

Весь фокус в том, что один исполняемый файл может содержать произвольное количество сервисов. Для этого и нужен массив, а по пустому элементу определяется его конец.

> sniknik © (27.10.03 15:06) [4]

Хороший пример, но не могу понять зачем создавать еще один поток? Дело в том, что функция ServiceMain и без этого все равно вызывается в отдельном потоке (а вот CtrlHandler - в главном). Стало быть, простое GetCurrentThread в ServiceMain дает хэндл потока, которым можно управлять из CtrlHandler через глобальную переменную. И тогда не приходится плодить лишних сущностей, расходуя лишние ресурсы.


 
sniknik   (2003-10-27 17:00) [7]

> Хороший пример, но не могу понять зачем создавать еще один поток?
я там пояснял что просто для примера (что так можно и все), вообще вся програмка это один большой пример ничего больше, не заметили там протоколируется любое действие (а где такое нужно кроме как в примере?, при разборе как это работает).


 
Polevi   (2003-10-27 18:43) [8]

>Юрий Зотов © (27.10.03 15:36) [6]
я в курсе, но у меня работает и так, вот как бывает :-)


 
Юрий Зотов   (2003-10-27 19:12) [9]

> Polevi © (27.10.03 18:43) [8]

Возможно удачное совпадение - после структуры в памяти идут нули. По ним и определяется "конец массива".



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

Форум: "Потрепаться";
Текущий архив: 2003.11.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.009 c
3-56465
Raduga
2003-10-28 09:02
2003.11.17
Отображение датывремени


3-56530
Newman
2003-10-26 16:56
2003.11.17
Как сохранить таблицу


14-56852
chs2r
2003-10-27 15:34
2003.11.17
АТ-команды на мобильники


8-56779
Hatawa
2003-07-20 18:17
2003.11.17
Почему StretchBlt при использовании портит рисунок?


14-56836
Vorobyev Sergey
2003-10-28 06:58
2003.11.17
Сегодня родился Билл Гейтс





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский