Форум: "Потрепаться";
Текущий архив: 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