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

Вниз

Запуск программы как службы. Очень нужна помощь.   Найти похожие ветки 

 
m52   (2005-05-24 10:17) [0]

Здравствуйте!
--------------

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

Что для этого нужно?
Что нужно переделать в программе, чтобы она работала как служба?
Чем отличается код, написанный просто как приложение и код, написанный для работы приложения как службы.

Очень нужна помощь.
Заранее благодарен.


 
Digitman ©   (2005-05-24 10:33) [1]


> Что для этого нужно?
> Что нужно переделать в программе, чтобы она работала как
> служба?


для этого нужно было изначально создать проект приложения не как File -> New.. -> Application, а как File -> New.. -> Service Application


> Чем отличается код, написанный просто как приложение и код,
> написанный для работы приложения как службы.


весьма многим
начиная с того, что VCL-приложение-сервис использует в качестве базового класс TServiceApplication, в то время как обычное приложение - класс TApplication.


 
m52   (2005-05-24 10:40) [2]

Т.е. получается так, что нельзя сделать так, чтобы приложение запускалось опционально
1) как служба
2) как приложение

Видимо нужно жестко завязывать код программы либо под службу, либо под приложение.


 
Digitman ©   (2005-05-24 10:46) [3]


> m52   (24.05.05 10:40) [2]


> Т.е. получается так, что нельзя сделать так, чтобы приложение
> запускалось опционально
> 1) как служба
> 2) как приложение


почему нельзя ? можно !


> Видимо нужно жестко завязывать код программы либо под службу,
> либо под приложение


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


 
Digitman ©   (2005-05-24 11:09) [4]

это - в качестве комментария к ветвлению :

uses
 Forms,
 SvcMgr,
 FormMain in "SvcMain.pas" {MainForm: TMainForm},
 SvcMain in "SvcMain.pas" {MainForm: TForm},

{$R *.RES}

begin
//если в ком.строке обнаружен 1-й параметр "/GUI"
//стартуем как обычное приложение
 if ParamStr(1) = "/GUI" then
   begin
    Forms.Application.Initialize;
    Forms.Application.CreateForm(TMainForm, MainForm);
    Forms.Application.Run;
   end
//иначе как сервис-приложение
 else
   begin
    SvcMgr.Application.Initialize;
    SvcMgr.Application.CreateForm(TMainService, MainService);
    SvcMgr.Application.Run;
   end;
end.


 
Digitman ©   (2005-05-24 11:17) [5]

вероятно, можно обойтись и без анализа ком.строки при принятии решения о ветвлении

родительским процессом для вновь стартуемого сервис-процесса, по идее, должен выступать процесс svchost.exe .. это условие, вероятно, и следует анализировать в dpr при принятии решения


 
m52   (2005-05-24 11:38) [6]

Спасибо. Попробую.


 
Eraser ©   (2005-05-24 11:40) [7]

Digitman ©   (24.05.05 11:17) [5]

В Borland Socket Server"e анализируется так:


function StartService: Boolean;
var
 Mgr, Svc: Integer;
 UserName, ServiceStartName: string;
 Config: Pointer;
 Size: DWord;
begin
 Result := False;
 Mgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
 if Mgr <> 0 then
 begin
   Svc := OpenService(Mgr, PChar(SServiceName), SERVICE_ALL_ACCESS);
   Result := Svc <> 0;
   if Result then
   begin
     QueryServiceConfig(Svc, nil, 0, Size);
     Config := AllocMem(Size);
     try
       QueryServiceConfig(Svc, Config, Size, Size);
       ServiceStartName := PQueryServiceConfig(Config)^.lpServiceStartName;
       if CompareText(ServiceStartName, "LocalSystem") = 0 then
         ServiceStartName := "SYSTEM";
     finally
       Dispose(Config);
     end;
     CloseServiceHandle(Svc);
   end;
   CloseServiceHandle(Mgr);
 end;
 if Result then
 begin
   Size := 256;
   SetLength(UserName, Size);
   GetUserName(PChar(UserName), Size);
   SetLength(UserName, StrLen(PChar(UserName)));
   Result := CompareText(UserName, ServiceStartName) = 0;
 end;
end;


 
Digitman ©   (2005-05-24 11:48) [8]


> Eraser ©   (24.05.05 11:40) [7]


ерунду городишь
это - из другой оперы и к сабжу никакого отношения не имеет


 
Eraser ©   (2005-05-24 11:52) [9]

Digitman ©   (24.05.05 11:48) [8]

Не! Это как раз по сабжу, просто название ф-ии с толку сбивает, надо было её называть IsStartService.


 
Digitman ©   (2005-05-24 12:08) [10]


> Eraser ©   (24.05.05 11:52) [9]


ты "смотришь в книгу - видишь фигу")


 
Digitman ©   (2005-05-24 12:16) [11]


> Eraser


в BSS решение о ветвлении принимается опять же либо по наличию ключа в ком.строке либо по наличию соотв.записи в реестре.


 
Eraser ©   (2005-05-24 16:54) [12]

Digitman ©   (24.05.05 12:16) [11]

Вот код загрузки приложения/сервиса:

begin
 if not Installing then
 begin
   CreateMutex(nil, True, "SCKTSRVR");
   if GetLastError = ERROR_ALREADY_EXISTS then
   begin
     MessageBox(0, PChar(SAlreadyRunning), SApplicationName, MB_ICONERROR);
     Halt;
   end;
 end;
 if Installing or StartService then
 begin
   SvcMgr.Application.Initialize;
   SocketService := TSocketService.CreateNew(SvcMgr.Application, 0);
   SvcMgr.Application.CreateForm(TSocketForm, SocketForm);
   SvcMgr.Application.Run;
 end else
 begin
   Forms.Application.ShowMainForm := False;
   Forms.Application.Initialize;
   Forms.Application.CreateForm(TSocketForm, SocketForm);
   SocketForm.Initialize(False);
   Forms.Application.Run;
 end;
end.

вот код ф-ии Installing


function Installing: Boolean;
begin
 Result := FindCmdLineSwitch("INSTALL",["-","\","/"], True) or
           FindCmdLineSwitch("UNINSTALL",["-","\","/"], True);
end;


Installing используется чисто для установки деинсталляции сервиса.

Соответственно решение о том сервис/не_сервис принимается в ф-ии StartService...
Или я что-то не допонял...
Тема интересная... самому в скором времени понадобится.


 
Digitman ©   (2005-05-24 17:04) [13]


> Соответственно решение о том сервис/не_сервис принимается
> в ф-ии StartService...


да галиматья !!)

мало ли чего в реестре прописано !?)

я туда накидать всякой похожей дряни могу и безо всякого /INSTALL .. но от этого всяка дрянь, на которую я опять же могу сослаться из реестра, вовсе не обязана быть натурально сервисом ...


 
Игорь Шевченко ©   (2005-05-24 17:06) [14]

Digitman ©   (24.05.05 12:16) [11]


> в BSS решение о ветвлении принимается опять же либо по наличию
> ключа в ком.строке либо по наличию соотв.записи в реестре.


А вроде без записи в реестре сервисом стать не получится ? Или я чего не понимаю ?


 
Eraser ©   (2005-05-24 17:09) [15]

Digitman ©   (24.05.05 17:04) [13]

Так значит самый надёжный вариант определения сервис/несервис - проверять родительский процесс?
имхо наверное тогда стОит проверять по параметру при запуске и не парить себе мОзги... )


 
Digitman ©   (2005-05-24 17:09) [16]


> Игорь Шевченко ©   (24.05.05 17:06) [14]


а вроде ком.строка, имеющая в своем контексте ключи вида /install, не обязана быть ком.строкой, имеющей ОБЯЗАТЕЛЬНОЕ отношение к сервисам ?


 
Digitman ©   (2005-05-24 17:10) [17]


> Eraser ©   (24.05.05 17:09) [15]
> Digitman ©   (24.05.05 17:04) [13]
>
> Так значит самый надёжный вариант определения сервис/несервис
> - проверять родительский процесс?


мне так показалось.
думаю, ИШ прояснит ситуацию ..


 
Игорь Шевченко ©   (2005-05-24 18:07) [18]

Digitman ©   (24.05.05 17:09) [16]


> а вроде ком.строка, имеющая в своем контексте ключи вида
> /install, не обязана быть ком.строкой, имеющей ОБЯЗАТЕЛЬНОЕ
> отношение к сервисам ?


Абсолютно не обязана. Я навскидку могу написать программу, которая по ключу /Install будет выполнять форматирование винчестера.

Я к другому - сервис, он обязан придерживаться протокола взаимодействия с менеджером сервисов, и прочая и прочая. И запускаться он (сервис) будет ТОЛЬКО services.exe и никем более.


 
ORMADA ©   (2005-05-25 07:19) [19]

тоже заинтересовала данная тема но только не понял как проанализировать что при старте сервис-процесса выступает процесс svchost.exe ?

==>Digitman ©   (24.05.05 11:17) [5]
вероятно, можно обойтись и без анализа ком.строки при принятии решения о ветвлении родительским процессом для вновь стартуемого сервис-процесса, по идее, должен выступать процесс svchost.exe .. это условие, вероятно, и следует анализировать в dpr при принятии решения


 
Digitman ©   (2005-05-25 08:17) [20]


> ORMADA


NtQuerySystemInformation() infoclass = SystemProcessThreadInfo


 
Warlock ©   (2005-06-10 06:15) [21]

Создаешь ServiceApplication. Код ServiceExecute:

procedure THaspRunnerService.ServiceExecute(Sender: TService);
var hwndHandle : THANDLE;
begin
WinExec("Путь и имя программы которую хочешь запускать",SW_SHOWMINNOACTIVE);
while not Terminated do
  ServiceThread.ProcessRequests(True);
hwndHandle:=FindWindow(Nil, "Тут заголовок главного окна программы");
if hwndHandle<>0 then
 PostMessage(hwndHandle, WM_QUIT, 0, 0);
end;

Способ может не лучший, но работал



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

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

Наверх




Память: 0.53 MB
Время: 0.043 c
3-1119542398
Koala
2005-06-23 19:59
2005.08.07
Помогите организовать ХП (Firebird)


8-1112253055
ndis
2005-03-31 11:10
2005.08.07
Как сделать прокрутку AVI файла , чтобы его было сквозь картинку.


1-1121898716
MAVr
2005-07-21 02:31
2005.08.07
Работа с папками…


1-1121755213
WondeRu
2005-07-19 10:40
2005.08.07
Ошибка при создании вариантного массива


8-1112169792
WondeRu
2005-03-30 12:03
2005.08.07
Direct3D. Полигон