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


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


С уважением, Vasilisk
...
Рейтинг: 0 / 0
Останов себя как службы
    #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
Останов себя как службы
    #39498429
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_, прямое
Код: pascal
1.
ExitProcess(0);


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

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


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