Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Останов себя как службы / 4 сообщений из 4, страница 1 из 1
01.08.2017, 13:32:25
    #39498357
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Останов себя как службы
В службе запускается поток. Иногда в этом потоке наступает такое событие, когда нужно завершить всю службу. Как это правильно сделать? Просмотр исходников дал такой способ
Код: pascal
1.
PostThreadMessage(FService.ServiceThread.ThreadID, CM_SERVICE_CONTROL_CODE, SERVICE_CONTROL_STOP, 0);


Все работает. Но может есть, что-то более прямое? А то какой-то костыльностью попахивает


С уважением, Vasilisk
...
Рейтинг: 0 / 0
01.08.2017, 14:11:33
    #39498401
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Останов себя как службы
Я так делаю. Подходит для всех сервисов, а не только своего.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
function StartService(const Name: PChar): boolean;
var SvcMgr: SC_HANDLE;

    function StopService(Name: PChar; SvcMgr: SC_HANDLE): boolean;
    var Svc: SC_HANDLE;
        p: pchar;
    begin
        result := false;
        Svc := OpenService(SvcMgr, Name, SERVICE_ALL_ACCESS);
        if Svc = 0 then exit; //RaiseLastOSError;
        p := nil;
        try
            if not WinSvc.StartService(Svc, 0, p) then
                //RaiseLastOSError
            else
                result := true;
        finally
            CloseServiceHandle(Svc);
        end;
    end;

begin
    result := false;
    SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
    if SvcMgr = 0 then RaiseLastOSError;
    try
        result := StopService(Name, SvcMgr);
    finally
        CloseServiceHandle(SvcMgr);
    end;
end;

function StopService(const Name: PChar): boolean;
var SvcMgr: SC_HANDLE;

    function StopService(Name: PChar; SvcMgr: SC_HANDLE): boolean;
    var Svc: SC_HANDLE;
        lp: SERVICE_STATUS;
    begin
        result := false;
        Svc := OpenService(SvcMgr, Name, SERVICE_ALL_ACCESS);
        if Svc = 0 then exit; //RaiseLastOSError;
        try
            if not ControlService(Svc, SERVICE_CONTROL_STOP, lp) then
                //RaiseLastOSError
            else
                result := true;
        finally
            CloseServiceHandle(Svc);
        end;
    end;

begin
    result := false;
    SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
    if SvcMgr = 0 then RaiseLastOSError;
    try
        result := StopService(Name, SvcMgr);
    finally
        CloseServiceHandle(SvcMgr);
    end;
end;


Модуль WinSvc вроде нужен.

Завалялся еще такой модуль:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
{ 
  The following class TServiceManager can be used to manage your NT-Services. 
  You can do things like start, stop, pause or querying a services status. 
}

 { 
  Die folgende Klasse TServiceManager kann verwendet werden, um NT-Dienste 
  zu verwalten. Hierbei gibt es Funktionen wie Start, Stop, Pause sowie 
  Statusabfragen. 
}


 //  Thanks for this one to Frederik Schaller as well - it's a co-work } 

unit ServiceManager;

 interface

 uses
   SysUtils, Windows, WinSvc;

 type

   TServiceManager = class
   private
     { Private declarations }
     ServiceControlManager: SC_Handle;
     ServiceHandle: SC_Handle;
   protected
     function DoStartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
   public
     { Public declarations }
     function Connect(MachineName: PChar = nil; DatabaseName: PChar = nil;
       Access: DWORD = SC_MANAGER_ALL_ACCESS): Boolean;  // Access may be SC_MANAGER_ALL_ACCESS 
    function OpenServiceConnection(ServiceName: PChar): Boolean;
     function StartService: Boolean; overload; // Simple start 
    function StartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
       overload; // More complex start 
    function StopService: Boolean;
     procedure PauseService;
     procedure ContinueService;
     procedure ShutdownService;
     procedure DisableService;
     function GetStatus: DWORD;
     function ServiceRunning: Boolean;
     function ServiceStopped: Boolean;
   end;

 implementation

 { TServiceManager }

 function TServiceManager.Connect(MachineName, DatabaseName: PChar;
   Access: DWORD): Boolean;
 begin
   Result := False;
   { open a connection to the windows service manager }
   ServiceControlManager := OpenSCManager(MachineName, DatabaseName, Access);
   Result := (ServiceControlManager <> 0);
 end;


 function TServiceManager.OpenServiceConnection(ServiceName: PChar): Boolean;
 begin
   Result := False;
   { open a connetcion to a specific service }
   ServiceHandle := OpenService(ServiceControlManager, ServiceName, SERVICE_ALL_ACCESS);
   Result := (ServiceHandle <> 0);
 end;

 procedure TServiceManager.PauseService;
 var
   ServiceStatus: TServiceStatus;
 begin
   { Pause the service: attention not supported by all services }
   ControlService(ServiceHandle, SERVICE_CONTROL_PAUSE, ServiceStatus);
 end;

 function TServiceManager.StopService: Boolean;
 var
   ServiceStatus: TServiceStatus;
 begin
   { Stop the service }
   Result := ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus);
 end;

 procedure TServiceManager.ContinueService;
 var
   ServiceStatus: TServiceStatus;
 begin
   { Continue the service after a pause: attention not supported by all services }
   ControlService(ServiceHandle, SERVICE_CONTROL_CONTINUE, ServiceStatus);
 end;

 procedure TServiceManager.ShutdownService;
 var
   ServiceStatus: TServiceStatus;
 begin
   { Shut service down: attention not supported by all services }
   ControlService(ServiceHandle, SERVICE_CONTROL_SHUTDOWN, ServiceStatus);
 end;

 function TServiceManager.StartService: Boolean;
 begin
   Result := DoStartService(0, '');
 end;

 function TServiceManager.StartService(NumberOfArgument: DWORD;
   ServiceArgVectors: PChar): Boolean;
 begin
   Result := DoStartService(NumberOfArgument, ServiceArgVectors);
 end;

 function TServiceManager.GetStatus: DWORD;
 var
   ServiceStatus: TServiceStatus;
 begin
 { Returns the status of the service. Maybe you want to check this 
  more than once, so just call this function again. 
  Results may be: SERVICE_STOPPED 
                  SERVICE_START_PENDING 
                  SERVICE_STOP_PENDING 
                  SERVICE_RUNNING 
                  SERVICE_CONTINUE_PENDING 
                  SERVICE_PAUSE_PENDING 
                  SERVICE_PAUSED   }
   Result := 0;
   QueryServiceStatus(ServiceHandle, ServiceStatus);
   Result := ServiceStatus.dwCurrentState;
 end;

 procedure TServiceManager.DisableService;
 begin
   { Implementation is following... }
 end;

 function TServiceManager.ServiceRunning: Boolean;
 begin
   Result := (GetStatus = SERVICE_RUNNING);
 end;

 function TServiceManager.ServiceStopped: Boolean;
 begin
   Result := (GetStatus = SERVICE_STOPPED);
 end;

 function TServiceManager.DoStartService(NumberOfArgument: DWORD;
   ServiceArgVectors: PChar): Boolean;
 var
   err: integer;
 begin
   Result := WinSvc.StartService(ServiceHandle, NumberOfArgument, ServiceArgVectors);
 end;

 end.



Ну и у твоего сервиса есть TServiceController, который по идее должен обрабатывать SERVICE_CONTROL_STOP. :-)
...
Рейтинг: 0 / 0
01.08.2017, 14:35:36
    #39498429
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Останов себя как службы
_Vasilisk_, прямое
Код: pascal
1.
ExitProcess(0);


ControlService, но сервис на то и сервис, зачем ему exit?
...
Рейтинг: 0 / 0
01.08.2017, 16:01:11
    #39498482
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Останов себя как службы
wadmanЯ так делаюТак я знаю :)
Bred eFeM
Код: pascal
1.
ExitProcess(0)

Это вообще серпом по ...
Bred eFeMзачем ему exit?Такой хитрый сервис
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Останов себя как службы / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]