service.iss 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. [Code]
  2. type
  3. SERVICE_STATUS = record
  4. dwServiceType : cardinal;
  5. dwCurrentState : cardinal;
  6. dwControlsAccepted : cardinal;
  7. dwWin32ExitCode : cardinal;
  8. dwServiceSpecificExitCode : cardinal;
  9. dwCheckPoint : cardinal;
  10. dwWaitHint : cardinal;
  11. end;
  12. HANDLE = cardinal;
  13. const
  14. SERVICE_QUERY_CONFIG = $1;
  15. SERVICE_CHANGE_CONFIG = $2;
  16. SERVICE_QUERY_STATUS = $4;
  17. SERVICE_START = $10;
  18. SERVICE_STOP = $20;
  19. SERVICE_ALL_ACCESS = $f01ff;
  20. SC_MANAGER_ALL_ACCESS = $f003f;
  21. SERVICE_WIN32_OWN_PROCESS = $10;
  22. SERVICE_WIN32_SHARE_PROCESS = $20;
  23. SERVICE_WIN32 = $30;
  24. SERVICE_INTERACTIVE_PROCESS = $100;
  25. SERVICE_BOOT_START = $0;
  26. SERVICE_SYSTEM_START = $1;
  27. SERVICE_AUTO_START = $2;
  28. SERVICE_DEMAND_START = $3;
  29. SERVICE_DISABLED = $4;
  30. SERVICE_DELETE = $10000;
  31. SERVICE_CONTROL_STOP = $1;
  32. SERVICE_CONTROL_PAUSE = $2;
  33. SERVICE_CONTROL_CONTINUE = $3;
  34. SERVICE_CONTROL_INTERROGATE = $4;
  35. SERVICE_STOPPED = $1;
  36. SERVICE_START_PENDING = $2;
  37. SERVICE_STOP_PENDING = $3;
  38. SERVICE_RUNNING = $4;
  39. SERVICE_CONTINUE_PENDING = $5;
  40. SERVICE_PAUSE_PENDING = $6;
  41. SERVICE_PAUSED = $7;
  42. ERROR_ACCESS_DENIED = 5;
  43. ERROR_CIRCULAR_DEPENDENCY = 1059;
  44. ERROR_DUPLICATE_SERVICE_NAME = 1078;
  45. ERROR_INVALID_HANDLE = 6;
  46. ERROR_INVALID_NAME = 123;
  47. ERROR_INVALID_PARAMETER = 87;
  48. ERROR_INVALID_SERVICE_ACCOUNT = 1057;
  49. ERROR_SERVICE_EXISTS = 1073;
  50. ERROR_SERVICE_MARKED_FOR_DELETE = 1072;
  51. // #######################################################################################
  52. // nt based service utilities
  53. // #######################################################################################
  54. function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
  55. external 'OpenSCManagerW@advapi32.dll stdcall';
  56. function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
  57. external 'OpenServiceW@advapi32.dll stdcall';
  58. function CloseServiceHandle(hSCObject :HANDLE): boolean;
  59. external 'CloseServiceHandle@advapi32.dll stdcall';
  60. function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
  61. external 'CreateServiceW@advapi32.dll stdcall';
  62. function DeleteService(hService :HANDLE): boolean;
  63. external 'DeleteService@advapi32.dll stdcall';
  64. function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
  65. external 'StartServiceW@advapi32.dll stdcall';
  66. function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
  67. external 'ControlService@advapi32.dll stdcall';
  68. function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
  69. external 'QueryServiceStatus@advapi32.dll stdcall';
  70. function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
  71. external 'QueryServiceStatus@advapi32.dll stdcall';
  72. function GetLastError(): dword;
  73. external 'GetLastError@kernel32.dll stdcall';
  74. function OpenServiceManager(): HANDLE;
  75. begin
  76. if UsingWinNT() = true then begin
  77. Result := OpenSCManager('', 'ServicesActive', SC_MANAGER_ALL_ACCESS);
  78. if Result = 0 then
  79. MsgBox(ExpandConstant('{cm:ServiceManagerUnavailable}'), mbError, MB_OK);
  80. end
  81. else begin
  82. MsgBox('only nt based systems support services', mbError, MB_OK);
  83. Result := 0;
  84. end
  85. end;
  86. function IsServiceInstalled(ServiceName: string): boolean;
  87. var
  88. hSCM : HANDLE;
  89. hService: HANDLE;
  90. begin
  91. hSCM := OpenServiceManager();
  92. Result := false;
  93. if hSCM <> 0 then begin
  94. hService := OpenService(hSCM, ServiceName, SERVICE_QUERY_CONFIG);
  95. if hService <> 0 then begin
  96. Result := true;
  97. CloseServiceHandle(hService);
  98. end;
  99. CloseServiceHandle(hSCM);
  100. end
  101. end;
  102. function InstallService(FileName, ServiceName, DisplayName, Description: string; ServiceType, StartType: cardinal): boolean;
  103. var
  104. hSCM : HANDLE;
  105. hService: HANDLE;
  106. begin
  107. hSCM := OpenServiceManager();
  108. Result := false;
  109. if hSCM <> 0 then begin
  110. hService := CreateService(hSCM, ServiceName, DisplayName, SERVICE_ALL_ACCESS, ServiceType, StartType, 0, FileName,'', 0, '', '', '');
  111. if hService <> 0 then begin
  112. Result := true;
  113. // Win2K & WinXP supports aditional description text for services
  114. if Description <> '' then
  115. RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName, 'Description', Description);
  116. CloseServiceHandle(hService);
  117. end;
  118. CloseServiceHandle(hSCM);
  119. end;
  120. end;
  121. function RemoveService(ServiceName: string): boolean;
  122. var
  123. hSCM : HANDLE;
  124. hService: HANDLE;
  125. begin
  126. hSCM := OpenServiceManager();
  127. Result := false;
  128. if hSCM <> 0 then begin
  129. hService := OpenService(hSCM, ServiceName, SERVICE_DELETE);
  130. if hService <> 0 then begin
  131. Result := DeleteService(hService);
  132. CloseServiceHandle(hService);
  133. end;
  134. CloseServiceHandle(hSCM);
  135. end;
  136. end;
  137. function StartService(ServiceName: string): boolean;
  138. var
  139. hSCM : HANDLE;
  140. hService: HANDLE;
  141. begin
  142. hSCM := OpenServiceManager();
  143. Result := false;
  144. if hSCM <> 0 then begin
  145. hService := OpenService(hSCM, ServiceName, SERVICE_START);
  146. if hService <> 0 then begin
  147. Result := StartNTService(hService, 0, 0);
  148. CloseServiceHandle(hService);
  149. end;
  150. CloseServiceHandle(hSCM);
  151. end;
  152. end;
  153. function StopService(ServiceName: string): boolean;
  154. var
  155. hSCM : HANDLE;
  156. hService: HANDLE;
  157. Status : SERVICE_STATUS;
  158. begin
  159. hSCM := OpenServiceManager();
  160. Result := false;
  161. if hSCM <> 0 then begin
  162. hService := OpenService(hSCM, ServiceName, SERVICE_STOP);
  163. if hService <> 0 then begin
  164. Result := ControlService(hService, SERVICE_CONTROL_STOP, Status);
  165. CloseServiceHandle(hService);
  166. end;
  167. CloseServiceHandle(hSCM);
  168. end;
  169. end;
  170. function IsServiceRunning(ServiceName: string): boolean;
  171. var
  172. hSCM : HANDLE;
  173. hService: HANDLE;
  174. Status : SERVICE_STATUS;
  175. begin
  176. hSCM := OpenServiceManager();
  177. Result := false;
  178. if hSCM <> 0 then begin
  179. hService := OpenService(hSCM, ServiceName, SERVICE_QUERY_STATUS);
  180. if hService <> 0 then begin
  181. if QueryServiceStatus(hService, Status) then begin
  182. Result :=(Status.dwCurrentState = SERVICE_RUNNING);
  183. end;
  184. CloseServiceHandle(hService);
  185. end;
  186. CloseServiceHandle(hSCM);
  187. end
  188. end;
  189. function ServiceErrorToMessage(Error: word): string;
  190. begin
  191. case Error of
  192. ERROR_ACCESS_DENIED: Result := 'Access Denied';
  193. ERROR_CIRCULAR_DEPENDENCY: Result := 'Circular Dependency';
  194. ERROR_DUPLICATE_SERVICE_NAME: Result := 'Duplicate Service Name';
  195. ERROR_INVALID_HANDLE: Result := 'Invalid Handle';
  196. ERROR_INVALID_NAME: Result := 'Invalid Name';
  197. ERROR_INVALID_PARAMETER: Result := 'Invalid Parameter';
  198. ERROR_INVALID_SERVICE_ACCOUNT: Result := 'Invalid Service Account';
  199. ERROR_SERVICE_EXISTS: Result := 'Service Exists';
  200. ERROR_SERVICE_MARKED_FOR_DELETE: Result := 'Service Marked For Deletion';
  201. else
  202. Result := 'Unknown error: ' + IntToStr(Error);
  203. end;
  204. end;