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

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.08.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.029 c
14-1121747972
БарЛог
2005-07-19 08:39
2005.08.07
Не про Украину, а про природу =)


3-1119935983
АМБ
2005-06-28 09:19
2005.08.07
Необходимо в запросе извлечь месяц из поля даты


9-1113835930
_sHaDe_
2005-04-18 18:52
2005.08.07
Полёт пули(GLScene)


6-1114085582
Gek1
2005-04-21 16:13
2005.08.07
Проблема с TClientSocket


14-1121389485
Джо
2005-07-15 05:04
2005.08.07
To whom it may concern.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский