论坛风格切换切换到宽版
  • 6000阅读
  • 12回复

请教老虎版主关于安装系统服务脚本问题 [复制链接]

上一主题 下一主题
离线546242502
 

发帖
332
金钱
-3060
威望
-306
只看楼主 倒序阅读 0 发表于: 2015-08-09
http://bbs.hanzify.org/read-htm-tid-31361.html
帖子时间也很久远了,2005的,编译脚本不是编译时报错就是安装时报错?






脚本文件: 基于_NT_的系统服务.zip (7 K) 下载次数:4

还有就是:

如何把安装目录自动指向剩余空间最大磁盘
http://bbs.hanzify.org/read-htm-tid-60402.html

5.5.2 restools增强版测试,并不能实现:





离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 1 发表于: 2015-08-09



离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 2 发表于: 2015-08-10
第一个问题:
InstExec 这个函数是以前 INNO 版本中的函数名称,现在这个函数的名称变了,新的名称是 Exec,具体用法你自己可以看帮助文件。
同时提醒你在 Unicode 版本 INNO 下需要修改某些调用的函数名,xxxA 要改成 xxxW,参看下面的问题。

第二个问题:
根据你其他提问中的问题,我估计你都是用的 Unicode 版本的 INNO 来编译所有脚本的。但是我过去给的示例脚本都是给 ANSI 版本的 INNO 使用的,你在拿过来给 UNICODE 版本使用时,有时需要适当调整一下。比如那个检查驱动器类型的函数,你就要调用与 Unicode 相应的函数:

function GetDriveType(lpDisk: String): integer;
// external 'GetDriveTypeA@kernel32.dll stdcall';
external 'GetDriveTypeW@kernel32.dll stdcall';


离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 3 发表于: 2015-08-10
回 2楼(gnatix) 的帖子
老虎版主,麻烦您了:
第一个问题:
不知道怎么修正对不对?



但是还是弹出这个对话框,也不知道怎么修正脚本?



因为只知道套用,也不知道到底哪里有问题,该如何修正?
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 4 发表于: 2015-08-11
其实已经跟你说了,你使用的是 Unicode 版本的 INNO,但是你复制的代码是给 ANSI 版本的。上面给了你一个例子,把 ANSI 版本的代码用于 Unicode 版本时,要调用的函数名要相应地更改,xxxA 要改成 xxxW。比如上面的例子是
function GetDriveType(lpDisk: String): integer;
external 'GetDriveTypeA@kernel32.dll stdcall';
要改成
function GetDriveType(lpDisk: String): integer;
external 'GetDriveTypeW@kernel32.dll stdcall';

你那个“ 基于 NT 的系统服务.iss” 中有许多这样的函数,你要一一修改。
  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;


离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 5 发表于: 2015-08-11
回 4楼(gnatix) 的帖子
gnatix:其实已经跟你说了,你使用的是 Unicode 版本的 INNO,但是你复制的代码是给 ANSI 版本的。上面给了你一个例子,把 ANSI 版本的代码用于 Unicode 版本时,要调用的函数名要相应地更改,xxxA 要改成 xxxW .. (2015-08-11 04:52) 

谢谢老虎版主的解答,我最先看能编译通过,就没去看,自己粗心大意了
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 6 发表于: 2015-08-11
回 4楼(gnatix) 的帖子
gnatix:其实已经跟你说了,你使用的是 Unicode 版本的 INNO,但是你复制的代码是给 ANSI 版本的。上面给了你一个例子,把 ANSI 版本的代码用于 Unicode 版本时,要调用的函数名要相应地更改,xxxA 要改成 xxxW .. (2015-08-11 04:52) 

谢谢老虎版主,该脚本全部测试可用了!
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 7 发表于: 2015-08-11
回 4楼(gnatix) 的帖子
老虎版主,还想问一个问题?
基于 NT 的系统服务.iss
您修正的这个脚本,编译后运行程序一闪即逝---->安装 退出代码1  安装程序初始化失败。



删除下面这些代码就可以显示安装界面正常安装了:
  1. function InitializeSetup(): boolean;
  2. begin
  3. if IsServiceInstalled('myservice') = false then begin
  4.   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
  5.   StartService('myservice');
  6.   StopService('myservice');
  7.   // after stopping a service you should wait some seconds before removing
  8.   RemoveService('myservice');
  9.   // otherwise removing can fail
  10.   end
  11. end
  12. else if IsServiceRunning('myservice') then
  13.   MsgBox('myservice is running',mbInformation, MB_OK);
  14. Result := false
  15. end;
应该是上面这些代码的问题,但是我不知道怎么修改,请教老虎版主能修改一下?

还有就是该脚本在 RemoveService('myservice'); 移除后能安装服务,但是不能实现删除服务?
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 8 发表于: 2015-08-12
我觉得你要先搞清楚自己是要达到什么目的。别人的代码充其量只是示例而已,不是一定完全是针对你的特定目的的。要把它用来达到你的特定目的,一般还需要你对代码进行一些调整,这就要求你逐句分析和理解那些代码。
你用的代码本身就只是告诉你如何使用这些代码,这是主要目的,而不是显示安装程序界面,所以作者把示例代码有意放在 function InitializeSetup() 里面,而且 Result := false; 就是说,他是有意不真正启动安装程序。如果你想要显示安装程序,你只要改成 Result := true; 就行了,而不是删除那些用来告诉你如何使用代码的代码。
继续加油!
Ich hoffe, du verstehst mich nicht falsch.
离线546242502

发帖
332
金钱
-3060
威望
-306
只看该作者 9 发表于: 2015-08-12
回 8楼(gnatix) 的帖子
gnatix:我觉得你要先搞清楚自己是要达到什么目的。别人的代码充其量只是示例而已,不是一定完全是针对你的特定目的的。要把它用来达到你的特定目的,一般还需要你对代码进行一些调整,这就要求 .. (2015-08-12 04:22) 

谢谢老虎版主的鼓励,这两天学到许多,自己能处理些问题了;

老虎版主,您看下这样改有问题不?

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  case CurPageID of
    wpReady:       //安装开始前才开始添加
      begin
      if IsServiceInstalled('myservice') = false then
      begin
      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
       StartService('myservice');
       StopService('myservice');
       // after stopping a service you should wait some seconds before removing
       RemoveService('myservice');
       // otherwise removing can fail
      end
      end
      else if IsServiceRunning('myservice') then
       begin
       MsgBox('myservice is running',mbInformation, MB_OK);
       end;
      end;
  end;
  Result := True;
end;