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

Вниз

Запуск программы из службы   Найти похожие ветки 

 
ildarkh   (2006-10-05 13:23) [0]

Здравствуйте,
я написал службу, в которой запускаю Блокнот. Он запускается, но без окна, только как процесс в памяти. Надо, что бы окно появлялось. Что делать?

program Project2;
const
 ServiceName = "ReplicatorGuarder";
 ServiceDisplayName = "Ñëóæáà êîíòðîëÿ èñïîëíåíèÿ Ðåïëèêàòîðà";

function GetLastErrorText:string;
var
 dwSize:DWORD;
 lpszTemp:LPSTR;
begin
 dwSize:=512;
 lpszTemp:=nil;
 try
   GetMem(lpszTemp,dwSize);
   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
FORMAT_MESSAGE_ARGUMENT_ARRAY,
     nil,GetLastError,LANG_NEUTRAL,lpszTemp,dwSize,nil);
 finally
   Result:=StrPas(lpszTemp);
   FreeMem(lpszTemp);
 end;
end;

procedure ServiceStop;
begin
 if (hServerStopEvent>0) then
 begin
   SetEvent(hServerStopEvent);
 end;
end;

procedure AddToMessageLog(sMsg:string);
var
 sString:array [0..1] of string;
 hEventSource:THandle;
begin
 hEventSource:=RegisterEventSource(nil,ServiceName);

 if hEventSource>0 then
 begin
   sString[0]:=ServiceName+" error: "+IntToStr(dwErr);
   sString[1]:=sMsg;
   ReportEvent(hEventSource,EVENTLOG_ERROR_TYPE,0,0,nil,2,0,@sString,nil);
     DeregisterEventSource(hEventSource);
 end;
end;

function ReportStatusToSCMgr(dwState,dwExitCode,dwWait:DWORD):BOOL;
begin
    Result:=True;
    with ssStatus do
    begin
         if (dwState=SERVICE_START_PENDING) then
              dwControlsAccepted:=0
          else
              dwControlsAccepted:=SERVICE_ACCEPT_STOP;

         dwCurrentState:=dwState;
         dwWin32ExitCode:=dwExitCode;
         dwWaitHint:=dwWait;

         if (dwState=SERVICE_RUNNING) or (dwState=SERVICE_STOPPED) then
             dwCheckPoint:=0
         else
             inc(dwCheckPoint);
    end;
    Result:=SetServiceStatus(ServiceStatusHandle,ssStatus);
    //if not Result then AddToMessageLog("SetServiceStatus");
end;

procedure InstallService;
var
  schService:SC_HANDLE;
  schSCManager:SC_HANDLE;
  lpszPath:LPSTR;
  dwSize:DWORD;
begin
 dwSize:=512;
 GetMem(lpszPath,dwSize);
 if GetModuleFileName(0,lpszPath,dwSize)=0 then
 begin
   FreeMem(lpszPath);
   exit;
 end;

 schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
 if (schSCManager>0) then
 begin
   schService:=CreateService(schSCManager,ServiceName,ServiceDisplayName,
   SERVICE_ALL_ACCESS - 2,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
   SERVICE_ERROR_NORMAL,lpszPath,nil,nil,nil,nil,nil);
   FreeMem(lpszPath);
   if (schService>0) then
   begin
     CloseServiceHandle(schService);
   end
   else begin
   end;
 end
 else

end;

procedure UnInstallService;
var
 schService:SC_HANDLE;
 schSCManager:SC_HANDLE;
begin
  schSCManager:=OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if (schSCManager>0) then
  begin
    schService:=OpenService(schSCManager,ServiceName,SERVICE_ALL_ACCESS);
    if (schService>0) then
    begin
      // Try to stop service at first
      if ControlService(schService,SERVICE_CONTROL_STOP,ssStatus) then
      begin
         //Write("Stopping Service ");
         Sleep(1000);
         while (QueryServiceStatus(schService,ssStatus)) do
         begin
           if ssStatus.dwCurrentState=SERVICE_STOP_PENDING then
           begin
             //Write(".");
             Sleep(1000);
           end
           else
             break;
         end;
         if ssStatus.dwCurrentState=SERVICE_STOPPED then
           begin end
         else begin
           CloseServiceHandle(schService);
           CloseServiceHandle(schSCManager);
           exit;
         end;
       end;

       // Remove the service
       if (DeleteService(schService)) then
         begin end
       else
         begin end;

       CloseServiceHandle(schService);
     end
     else
       begin end;

     CloseServiceHandle(schSCManager);
   end
   else
     begin end;
end;

procedure ServiceStart;
var
 dwWait:DWORD;
 Si : TStartupInfo;
 p  : TProcessInformation;
begin
 // Report Status
 if not ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,3000) then exit;

 // Create the event object. The control handler function signals
 // this event when it receives the "stop" control code.
 hServerStopEvent:=CreateEvent(nil,TRUE,False,nil);
 if hServerStopEvent=0 then
 begin
   AddToMessageLog("CreateEvent");
   exit;
 end;

 if not ReportStatusToSCMgr(SERVICE_RUNNING,NO_ERROR,0) then
 begin
   CloseHandle(hServerStopEvent);
   exit;
 end;

 CreateProcess(nil,"notepad.exe",nil,nil,false,0, nil,nil,Si,p);

 while True do
 begin
   dwWait:=WaitforSingleObject(hServerStopEvent,1);
   if dwWait=WAIT_OBJECT_0 then
   begin
     CloseHandle(hServerStopEvent);
     exit;
   end;

   Sleep(1000*10);
 end;
end;

procedure Handler(dwCtrlCode:DWORD);stdcall;
begin
   // Handle the requested control code.
   case dwCtrlCode of

       SERVICE_CONTROL_STOP:
       begin
            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
            ServiceStop;
            ReportStatusToSCMgr(SERVICE_STOPPED,{GetLastError}0, 0);
            exit;
       end;

       SERVICE_CONTROL_INTERROGATE:
       begin
       end;

       SERVICE_CONTROL_PAUSE:
       begin
       end;

       SERVICE_CONTROL_CONTINUE:
       begin
       end;

       SERVICE_CONTROL_SHUTDOWN:
       begin
       end;

       // invalid control code
       else
   end;

   // Update the service status.
   ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
end;

procedure ServiceMain;
begin
    // Register the handler function with dispatcher;

ServiceStatusHandle:=RegisterServiceCtrlHandler(ServiceName,ThandlerFunction
(@Handler));
    if ServiceStatusHandle=0 then
    begin
         ReportStatusToSCMgr(SERVICE_STOPPED,GetLastError,0);
         exit;
    end;

    ssStatus.dwServiceType:=SERVICE_WIN32_OWN_PROCESS;
    ssStatus.dwServiceSpecificExitCode:=0;
    ssStatus.dwCheckPoint:=1;

    // Report current status to SCM (Service Control Manager)
    if not ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,3000) then
    begin
         ReportStatusToSCMgr(SERVICE_STOPPED,GetLastError,0);
         exit;
    end;

    // Start Service
    ServiceStart;
end;

begin

 if (ParamCount=1) then
 begin

   if Uppercase(ParamStr(1))="/INSTALL" then
   begin
     InstallService;
     Halt;
   end;

   if Uppercase(ParamStr(1))="/UNINSTALL" then
   begin
     UnInstallService;
     Halt;
   end;
 end;

 // Setup service table which define all services in this process
 with ServiceTableEntry[0] do
 begin
   lpServiceName:=ServiceName;
   lpServiceProc:=TServiceMainFunction(@ServiceMain);
 end;

 // Last entry in the table must have nil values to designate the end of the table
 with ServiceTableEntry[1] do
 begin
   lpServiceName:=nil;
   lpServiceProc:=nil;
 end;

 StartServiceCtrlDispatcher(ServiceTableEntry[0]);
end.


 
clickmaker ©   (2006-10-05 13:26) [1]

а зачем запускать из службы блокнот?


 
BiN ©   (2006-10-05 13:30) [2]

Единственное, что мне интересно, это как процесс запускается без инициализации STARTUPINFO.


 
Игорь Шевченко ©   (2006-10-05 13:53) [3]

Окно есть, только оно на другом десктопе. Я угадал ?


 
Polevi ©   (2006-10-05 13:59) [4]

разрешить службе взаимодействие с рабочим столом


 
han_malign ©   (2006-10-05 14:05) [5]


> разрешить службе взаимодействие с рабочим столом

- укорочу поиск
CreateService(...,SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS,...)


 
Ketmar ©   (2006-10-05 16:26) [6]

и, по-моему, стоит ещё проверять десктопы. на всякий случай. %-)


 
Eraser ©   (2006-10-05 22:43) [7]

> [0] ildarkh   (05.10.06 13:23)

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

остальные решения, в т.ч. и с SERVICE_INTERACTIVE_PROCESS не будут работать в Vist"е вообще, а в winXP будут глючить, если применять FUS.


 
Ketmar ©   (2006-10-05 22:46) [8]

>[7] Eraser(c) 5-Oct-2006, 22:43
>единственное общее решиние - для каждого нового
>пользователя (терминальной сессии) запускать GUI
>приложение-посредник
кстати, так обычно и делаю. видимо, интуитивно. %-)


 
Eraser ©   (2006-10-05 22:52) [9]

> [8] Ketmar ©   (05.10.06 22:46)

offtop:
а не в курсе, как в висте добраться до рабочего стола, когда еще ни один юзер не залогинен, и вообще в какой по счету терминальной сессии находится десктоп в этот момент?


 
Ketmar ©   (2006-10-05 23:31) [10]

>[9] Eraser(c) 5-Oct-2006, 22:52
>а не в курсе
а я висту в глаза не видел. %-)


 
Германн ©   (2006-10-06 01:25) [11]


> etmar ©   (05.10.06 23:31) [10]
>
> >[9] Eraser(c) 5-Oct-2006, 22:52
> >а не в курсе
> а я висту в глаза не видел. %-)
>

Зато я вижу висту вот уже более 10 лет. Глаза б мои её не видели б никогда! :-)


 
Игорь Шевченко ©   (2006-10-06 10:18) [12]

Германн ©   (06.10.06 01:25) [11]


> Зато я вижу висту вот уже более 10 лет.


Это наверное очень старая виста...


 
Германн ©   (2006-10-06 14:47) [13]

2 Игорь Шевченко ©   (06.10.06 10:18) [12]

> Это наверное очень старая виста...

Ага. И очень хреновая. Но именно её рекомендует использовать МВД. :-)


 
ildarkh   (2006-10-07 14:32) [14]

Всем спасибо, проблема решена.


 
ildarkh   (2006-10-07 14:37) [15]

Я использовал SERVICE_INTERACTIVE_PROCESS и работает нормально. У меня конечно запускается не блокнот, там программа в трее с диалоговым окном. Так вот, при запуске ОСи, сервис грузится, грузит и мою программу. Однако в трей она не вылазит, как если бы не использовался SERVICE_INTERACTIVE_PROCESS. Предполагаю, чисто интуитивно, она рановато грузится. Что сделать? Пока задержку поставлю, но сколько она держаться должна, точно не может быть известно.


 
Eraser ©   (2006-10-07 14:44) [16]

> [15] ildarkh   (07.10.06 14:37)

теперь нажми Выход из системы -> Сменить пользователя, зайди под другим пользователем и посмотри будет работать или нет :))



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

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

Наверх




Память: 0.52 MB
Время: 0.046 c
15-1169984485
hmmm
2007-01-28 14:41
2007.02.18
HTML


2-1169955441
vegarulez
2007-01-28 06:37
2007.02.18
Как правильно из DBGridColumnMoved вызвать DBGridCellClick?


2-1170333130
Destroyer
2007-02-01 15:32
2007.02.18
Как узнвать handle потока?


1-1166783436
STIK
2006-12-22 13:30
2007.02.18
Сохранение компоненты.


15-1169695931
Slider007
2007-01-25 06:32
2007.02.18
С днем рождения ! 25 января