杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1735|回复: 0

基于 NT 的系统服务

[复制链接]
发表于 2017-1-9 20:51:18 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. ;Inno Setup Extensions Knowledge Base
  2. ;Article 31 - Functions to Start, Stop, Install, Remove a NT Service
  3. ;http://www13.brinkster.com/vincenzog/isxart.asp?idart=31
  4. ;Author: Silvio Iaccarino
  5. ;Compiler: ISX 3.0.4
  6. ;

  7. [Setup]
  8. AppName=test
  9. AppVerName=test

  10. CreateAppDir=false
  11. UsePreviousAppDir=false
  12. UsePreviousGroup=false
  13. AlwaysShowComponentsList=false
  14. ShowComponentSizes=false
  15. FlatComponentsList=false
  16. UsePreviousSetupType=false
  17. UsePreviousTasks=false
  18. UsePreviousUserInfo=false
  19. DisableStartupPrompt=true

  20. [_ISTool]
  21. EnableISX=true

  22. [Code]
  23. type
  24. SERVICE_STATUS = record
  25.     dwServiceType    : cardinal;
  26.     dwCurrentState    : cardinal;
  27.     dwControlsAccepted  : cardinal;
  28.     dwWin32ExitCode    : cardinal;
  29.     dwServiceSpecificExitCode : cardinal;
  30.     dwCheckPoint    : cardinal;
  31.     dwWaitHint    : cardinal;
  32. end;
  33. HANDLE = cardinal;

  34. const
  35. SERVICE_QUERY_CONFIG  = $1;
  36. SERVICE_CHANGE_CONFIG  = $2;
  37. SERVICE_QUERY_STATUS  = $4;
  38. SERVICE_START    = $10;
  39. SERVICE_STOP    = $20;
  40. SERVICE_ALL_ACCESS  = $f01ff;
  41. SC_MANAGER_ALL_ACCESS  = $f003f;
  42. SERVICE_WIN32_OWN_PROCESS = $10;
  43. SERVICE_WIN32_SHARE_PROCESS = $20;
  44. SERVICE_WIN32    = $30;
  45. SERVICE_INTERACTIVE_PROCESS = $100;
  46. SERVICE_BOOT_START          = $0;
  47. SERVICE_SYSTEM_START        = $1;
  48. SERVICE_AUTO_START          = $2;
  49. SERVICE_DEMAND_START        = $3;
  50. SERVICE_DISABLED            = $4;
  51. SERVICE_DELETE              = $10000;
  52. SERVICE_CONTROL_STOP  = $1;
  53. SERVICE_CONTROL_PAUSE  = $2;
  54. SERVICE_CONTROL_CONTINUE = $3;
  55. SERVICE_CONTROL_INTERROGATE = $4;
  56. SERVICE_STOPPED    = $1;
  57. SERVICE_START_PENDING      = $2;
  58. SERVICE_STOP_PENDING        = $3;
  59. SERVICE_RUNNING            = $4;
  60. SERVICE_CONTINUE_PENDING    = $5;
  61. SERVICE_PAUSE_PENDING      = $6;
  62. SERVICE_PAUSED              = $7;

  63. // #######################################################################################
  64. // nt based service utilities
  65. // #######################################################################################
  66. function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
  67. external 'OpenSCManagerW@advapi32.dll stdcall';

  68. function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
  69. external 'OpenServiceW@advapi32.dll stdcall';

  70. function CloseServiceHandle(hSCObject :HANDLE): boolean;
  71. external 'CloseServiceHandle@advapi32.dll stdcall';

  72. function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
  73. external 'CreateServiceW@advapi32.dll stdcall';

  74. function DeleteService(hService :HANDLE): boolean;
  75. external 'DeleteService@advapi32.dll stdcall';

  76. function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
  77. external 'StartServiceW@advapi32.dll stdcall';

  78. function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
  79. external 'ControlService@advapi32.dll stdcall';

  80. function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
  81. external 'QueryServiceStatus@advapi32.dll stdcall';

  82. function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
  83. external 'QueryServiceStatus@advapi32.dll stdcall';

  84. function OpenServiceManager() : HANDLE;
  85. begin
  86. if UsingWinNT() = true then begin
  87.   Result := OpenSCManager('','ServicesActive',SC_MANAGER_ALL_ACCESS);
  88.   if Result = 0 then
  89.   MsgBox('the servicemanager is not available', mbError, MB_OK)
  90. end
  91. else begin
  92.   MsgBox('only nt based systems support services', mbError, MB_OK)
  93.   Result := 0;
  94. end
  95. end;

  96. function IsServiceInstalled(ServiceName: string) : boolean;
  97. var
  98. hSCM : HANDLE;
  99. hService: HANDLE;
  100. begin
  101. hSCM := OpenServiceManager();
  102. Result := false;
  103. if hSCM <> 0 then begin
  104.   hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG);
  105.         if hService <> 0 then begin
  106.             Result := true;
  107.             CloseServiceHandle(hService)
  108.   end;
  109.         CloseServiceHandle(hSCM)
  110. end
  111. end;

  112. function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
  113. var
  114. hSCM : HANDLE;
  115. hService: HANDLE;
  116. begin
  117. hSCM := OpenServiceManager();
  118. Result := false;
  119. if hSCM <> 0 then begin
  120.   hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','','');
  121.   if hService <> 0 then begin
  122.   Result := true;
  123.   // Win2K & WinXP supports aditional description text for services
  124.   if Description<> '' then
  125.     RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName,'Description',Description);
  126.   CloseServiceHandle(hService)
  127.   end;
  128.         CloseServiceHandle(hSCM)
  129. end
  130. end;

  131. function RemoveService(ServiceName: string) : boolean;
  132. var
  133. hSCM : HANDLE;
  134. hService: HANDLE;
  135. begin
  136. hSCM := OpenServiceManager();
  137. Result := false;
  138. if hSCM <> 0 then begin
  139.   hService := OpenService(hSCM,ServiceName,SERVICE_DELETE);
  140.         if hService <> 0 then begin
  141.             Result := DeleteService(hService);
  142.             CloseServiceHandle(hService)
  143.   end;
  144.         CloseServiceHandle(hSCM)
  145. end
  146. end;

  147. function StartService(ServiceName: string) : boolean;
  148. var
  149. hSCM : HANDLE;
  150. hService: HANDLE;
  151. begin
  152. hSCM := OpenServiceManager();
  153. Result := false;
  154. if hSCM <> 0 then begin
  155.   hService := OpenService(hSCM,ServiceName,SERVICE_START);
  156.         if hService <> 0 then begin
  157.         Result := StartNTService(hService,0,0);
  158.             CloseServiceHandle(hService)
  159.   end;
  160.         CloseServiceHandle(hSCM)
  161. end;
  162. end;

  163. function StopService(ServiceName: string) : boolean;
  164. var
  165. hSCM : HANDLE;
  166. hService: HANDLE;
  167. Status : SERVICE_STATUS;
  168. begin
  169. hSCM := OpenServiceManager();
  170. Result := false;
  171. if hSCM <> 0 then begin
  172.   hService := OpenService(hSCM,ServiceName,SERVICE_STOP);
  173.         if hService <> 0 then begin
  174.         Result := ControlService(hService,SERVICE_CONTROL_STOP,Status);
  175.             CloseServiceHandle(hService)
  176.   end;
  177.         CloseServiceHandle(hSCM)
  178. end;
  179. end;

  180. function IsServiceRunning(ServiceName: string) : boolean;
  181. var
  182. hSCM : HANDLE;
  183. hService: HANDLE;
  184. Status : SERVICE_STATUS;
  185. begin
  186. hSCM := OpenServiceManager();
  187. Result := false;
  188. if hSCM <> 0 then begin
  189.   hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS);
  190.     if hService <> 0 then begin
  191.   if QueryServiceStatus(hService,Status) then begin
  192.     Result :=(Status.dwCurrentState = SERVICE_RUNNING)
  193.         end;
  194.             CloseServiceHandle(hService)
  195.       end;
  196.         CloseServiceHandle(hSCM)
  197. end
  198. end;

  199. // #######################################################################################
  200. // create an entry in the services file
  201. // #######################################################################################
  202. function SetupService(service, port, comment: string) : boolean;
  203. var
  204. filename : string;
  205. s  : string;
  206. lines  : TArrayOfString;
  207. n  : longint;
  208. i  : longint;
  209. errcode  : integer;
  210. servnamlen : integer;
  211. error  : boolean;
  212. begin
  213. if UsingWinNT() = true then
  214.   filename := ExpandConstant('{sys}\drivers\etc\services')
  215. else
  216.   filename := ExpandConstant('{win}\services');

  217. if LoadStringsFromFile(filename,lines) = true then begin
  218.   Result  := true;
  219.   n  := GetArrayLength(lines) - 1;
  220.   servnamlen := Length(service);
  221.   error  := false;

  222.   for i:=0 to n do begin
  223.   if Copy(lines[i],1,1) <> '#' then begin
  224.     s := Copy(lines[i],1,servnamlen);
  225.     if CompareText(s,service) = 0 then
  226.     exit; // found service-entry

  227.     if Pos(port,lines[i]) > 0 then begin
  228.     error := true;
  229.     lines[i] := '#' + lines[i] + '  # disabled because collision with  ' + service + ' service';
  230.     end;
  231.   end
  232.   else if CompareText(Copy(lines[i],2,servnamlen),service) = 0 then begin
  233.     // service-entry was disabled
  234.     Delete(lines[i],1,1);
  235.     Result := SaveStringsToFile(filename,lines,false);
  236.     exit;
  237.   end;
  238.   end;

  239.   if error = true then begin
  240.   // save disabled entries
  241.   if SaveStringsToFile(filename,lines,false) = false then begin
  242.     Result := false;
  243.     exit;
  244.   end;
  245.   end;

  246.   // create new service entry
  247.   s := service + '      ' + port + '          # ' + comment + #13#10;
  248.   if SaveStringToFile(filename,s,true) = false then begin
  249.   Result := false;
  250.   exit;
  251.   end;

  252.   if error = true then begin
  253.   MsgBox('the ' + service + ' port was already used. The old service is disabled now. You should check the services file manually now.',mbInformation,MB_OK);
  254.   Exec('notepad.exe',filename,GetCurrentDir(),SW_SHOWNORMAL,ewWaitUntilTerminated,errcode);
  255.   end;
  256. end
  257. else
  258.   Result := false;
  259. end;

  260. // #######################################################################################
  261. // version functions
  262. // #######################################################################################
  263. function CheckVersion(Filename : string;hh,hl,lh,ll : integer) : boolean;
  264. var
  265. VersionMS : cardinal;
  266. VersionLS : cardinal;
  267. CheckMS  : cardinal;
  268. CheckLS  : cardinal;
  269. begin
  270. if GetVersionNumbers(Filename,VersionMS,VersionLS) = false then
  271.   Result := false
  272. else begin
  273.   CheckMS := (hh shl $10) or hl;
  274.   CheckLS := (lh shl $10) or ll;
  275.   Result := (VersionMS > CheckMS) or ((VersionMS = CheckMS) and (VersionLS >= CheckLS));
  276. end;
  277. end;

  278. // Some examples for version checking
  279. function NeedShellFolderUpdate() : boolean;
  280. begin
  281. Result := CheckVersion('ShFolder.dll',5,50,4027,300) = false;
  282. end;

  283. function NeedVCRedistUpdate() : boolean;
  284. begin
  285. Result := (CheckVersion('mfc42.dll',6,0,8665,0) = false)
  286.   or (CheckVersion('msvcrt.dll',6,0,8797,0) = false)
  287.   or (CheckVersion('comctl32.dll',5,80,2614,3600) = false);
  288. end;

  289. function NeedHTMLHelpUpdate() : boolean;
  290. begin
  291. Result := CheckVersion('hh.exe',4,72,0,0) = false;
  292. end;

  293. function NeedWinsockUpdate() : boolean;
  294. begin
  295. Result := (UsingWinNT() = false) and (CheckVersion('mswsock.dll',4,10,0,1656) = false);
  296. end;

  297. function NeedDCOMUpdate() : boolean;
  298. begin
  299. Result := (UsingWinNT() = false) and (CheckVersion('oleaut32.dll',2,30,0,0) = false);
  300. end;

  301. // function IsServiceInstalled(ServiceName: string) : boolean;
  302. // function IsServiceRunning(ServiceName: string) : boolean;
  303. // function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
  304. // function RemoveService(ServiceName: string) : boolean;
  305. // function StartService(ServiceName: string) : boolean;
  306. // function StopService(ServiceName: string) : boolean;

  307. // function SetupService(service, port, comment: string) : boolean;

  308. // function CheckVersion(Filename : string;hh,hl,lh,ll : integer) : boolean;

  309. //这是重点
  310. function InitializeSetup(): boolean;
  311. begin
  312. if IsServiceInstalled('myservice') = false then begin
  313.   if InstallService('c:\winnt\system32\myservice.exe','myservice','my service','my service is doing usefull things',SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START) = true then begin
  314.   StartService('myservice');
  315.   StopService('myservice');
  316.   // after stopping a service you should wait some seconds before removing
  317.   RemoveService('myservice');
  318.   // otherwise removing can fail
  319.   end
  320. end
  321. else if IsServiceRunning('myservice') then
  322.   MsgBox('myservice is running',mbInformation, MB_OK);

  323. Result := false
  324. end;
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-5-19 22:39 , Processed in 0.111153 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表