论坛风格切换切换到宽版
  • 19176阅读
  • 13回复

[请教]Inno setup如何把文件注册为系统服务? [复制链接]

上一主题 下一主题
离线吕达嵘
 

发帖
2855
金钱
9785
威望
154
只看楼主 倒序阅读 0 发表于: 2005-02-24
Inno setup如何把文件注册为系统服务?
好象 regserver 只是注册控件吧?
帮助文件中又好象找不到
伏 案 埋 首 清 月 夜, 苦 为 己 任 利 众 人。
欣 然 放 眼 新 世 纪, 最 美 还 是 我 中 文。
Welcome to 汉化新世纪............
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 1 发表于: 2005-02-24
这是一个如何检查、安装、启动、停止以及删除基于 NT 的服务的脚本。
下面提到的 Compiler: ISX 3.0.4 不需要,因为已经融合到 Inno Setup 4 以后的版本中了。
QUOTE

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

[Setup]
AppName=test
AppVerName=test

CreateAppDir=false
UsePreviousAppDir=false
UsePreviousGroup=false
AlwaysShowComponentsList=false
ShowComponentSizes=false
FlatComponentsList=false
UsePreviousSetupType=false
UsePreviousTasks=false
UsePreviousUserInfo=false
DisableStartupPrompt=true

[_ISTool]
EnableISX=true

[Code]
type
     SERVICE_STATUS = record
         dwServiceType    : cardinal;
         dwCurrentState    : cardinal;
         dwControlsAccepted       : cardinal;
         dwWin32ExitCode    : cardinal;
         dwServiceSpecificExitCode      : cardinal;
         dwCheckPoint    : cardinal;
         dwWaitHint         : cardinal;
     end;
     HANDLE = cardinal;

const
     SERVICE_QUERY_CONFIG  = $1;
     SERVICE_CHANGE_CONFIG  = $2;
     SERVICE_QUERY_STATUS  = $4;
     SERVICE_START    = $10;
     SERVICE_STOP    = $20;
     SERVICE_ALL_ACCESS       = $f01ff;
     SC_MANAGER_ALL_ACCESS  = $f003f;
     SERVICE_WIN32_OWN_PROCESS      = $10;
     SERVICE_WIN32_SHARE_PROCESS      = $20;
     SERVICE_WIN32    = $30;
     SERVICE_INTERACTIVE_PROCESS = $100;
     SERVICE_BOOT_START          = $0;
     SERVICE_SYSTEM_START        = $1;
     SERVICE_AUTO_START          = $2;
     SERVICE_DEMAND_START        = $3;
     SERVICE_DISABLED            = $4;
     SERVICE_DELETE              = $10000;
     SERVICE_CONTROL_STOP  = $1;
     SERVICE_CONTROL_PAUSE  = $2;
     SERVICE_CONTROL_CONTINUE      = $3;
     SERVICE_CONTROL_INTERROGATE = $4;
     SERVICE_STOPPED    = $1;
     SERVICE_START_PENDING      = $2;
     SERVICE_STOP_PENDING        = $3;
     SERVICE_RUNNING            = $4;
     SERVICE_CONTINUE_PENDING    = $5;
     SERVICE_PAUSE_PENDING      = $6;
     SERVICE_PAUSED              = $7;

// #######################################################################################
// nt based service utilities
// #######################################################################################
function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
external 'OpenSCManagerA@advapi32.dll stdcall';

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

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

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

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

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

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

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

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

function OpenServiceManager() : HANDLE;
begin
     if UsingWinNT() = true then begin
  Result := OpenSCManager('','ServicesActive',SC_MANAGER_ALL_ACCESS);
  if Result = 0 then
       MsgBox('the servicemanager is not available', mbError, MB_OK)
     end
     else begin
       MsgBox('only nt based systems support services', mbError, MB_OK)
       Result := 0;
     end
end;

function IsServiceInstalled(ServiceName: string) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG);
        if hService <> 0 then begin
            Result := true;
            CloseServiceHandle(hService)
  end;
        CloseServiceHandle(hSCM)
     end
end;

function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','','');
  if hService <> 0 then begin
       Result := true;
       // Win2K & WinXP supports aditional description text for services
       if Description<> '' then
    RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName,'Description',Description);
       CloseServiceHandle(hService)
  end;
        CloseServiceHandle(hSCM)
     end
end;

function RemoveService(ServiceName: string) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := OpenService(hSCM,ServiceName,SERVICE_DELETE);
        if hService <> 0 then begin
            Result := DeleteService(hService);
            CloseServiceHandle(hService)
  end;
        CloseServiceHandle(hSCM)
     end
end;

function StartService(ServiceName: string) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := OpenService(hSCM,ServiceName,SERVICE_START);
        if hService <> 0 then begin
             Result := StartNTService(hService,0,0);
            CloseServiceHandle(hService)
  end;
        CloseServiceHandle(hSCM)
     end;
end;

function StopService(ServiceName: string) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
     Status      : SERVICE_STATUS;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := OpenService(hSCM,ServiceName,SERVICE_STOP);
        if hService <> 0 then begin
             Result := ControlService(hService,SERVICE_CONTROL_STOP,Status);
            CloseServiceHandle(hService)
  end;
        CloseServiceHandle(hSCM)
     end;
end;

function IsServiceRunning(ServiceName: string) : boolean;
var
     hSCM      : HANDLE;
     hService: HANDLE;
     Status      : SERVICE_STATUS;
begin
     hSCM := OpenServiceManager();
     Result := false;
     if hSCM <> 0 then begin
  hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS);
         if hService <> 0 then begin
       if QueryServiceStatus(hService,Status) then begin
    Result :=(Status.dwCurrentState = SERVICE_RUNNING)
             end;
            CloseServiceHandle(hService)
      end;
        CloseServiceHandle(hSCM)
     end
end;

// #######################################################################################
// create an entry in the services file
// #######################################################################################
function SetupService(service, port, comment: string) : boolean;
var
     filename      : string;
     s       : string;
     lines  : TArrayOfString;
     n       : longint;
     i       : longint;
     errcode  : integer;
     servnamlen      : integer;
     error  : boolean;
begin
     if UsingWinNT() = true then
  filename := ExpandConstant('{sys}\drivers\etc\services')
     else
  filename := ExpandConstant('{win}\services');

     if LoadStringsFromFile(filename,lines) = true then begin
  Result  := true;
  n       := GetArrayLength(lines) - 1;
  servnamlen      := Length(service);
  error  := false;

  for i:=0 to n do begin
       if Copy(lines,1,1) <> '#' then begin
    s := Copy(lines,1,servnamlen);
    if CompareText(s,service) = 0 then
         exit; // found service-entry

    if Pos(port,lines) > 0 then begin
         error := true;
         lines := '#' + lines + '  # disabled because collision with  ' + service + ' service';
    end;
       end
       else if CompareText(Copy(lines,2,servnamlen),service) = 0 then begin
    // service-entry was disabled
    Delete(lines,1,1);
    Result := SaveStringsToFile(filename,lines,false);
    exit;
       end;
  end;

  if error = true then begin
       // save disabled entries
       if SaveStringsToFile(filename,lines,false) = false then begin
    Result := false;
    exit;
       end;
  end;

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

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

// #######################################################################################
// version functions
// #######################################################################################
function CheckVersion(Filename : string;hh,hl,lh,ll : integer) : boolean;
var
     VersionMS      : cardinal;
     VersionLS      : cardinal;
     CheckMS  : cardinal;
     CheckLS  : cardinal;
begin
     if GetVersionNumbers(Filename,VersionMS,VersionLS) = false then
  Result := false
     else begin
  CheckMS := (hh shl $10) or hl;
  CheckLS := (lh shl $10) or ll;
  Result := (VersionMS > CheckMS) or ((VersionMS = CheckMS) and (VersionLS >= CheckLS));
     end;
end;

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

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

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

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

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

// function IsServiceInstalled(ServiceName: string) : boolean;
// function IsServiceRunning(ServiceName: string) : boolean;
// function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
// function RemoveService(ServiceName: string) : boolean;
// function StartService(ServiceName: string) : boolean;
// function StopService(ServiceName: string) : boolean;

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

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


function InitializeSetup(): boolean;
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
  MsgBox('myservice is running',mbInformation, MB_OK);

     Result := false
end;

http://www13.brinkster.com/vincenzog/isxart.asp?idart=31
离线吕达嵘

发帖
2855
金钱
9785
威望
154
只看该作者 2 发表于: 2005-02-24
这么多?看了头大,我得慢慢琢磨,谢谢gnatix
伏 案 埋 首 清 月 夜, 苦 为 己 任 利 众 人。
欣 然 放 眼 新 世 纪, 最 美 还 是 我 中 文。
Welcome to 汉化新世纪............
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 3 发表于: 2005-02-24
QUOTE(吕达嵘 @ 2005年02月24日 14时36分)
这么多?看了头大,我得慢慢琢磨,谢谢gnatix
[snapback]191137[/snapback]


如果只是套用,那么只要关心红色部分就行了

function InitializeSetup(): boolean;
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
MsgBox('myservice is running',mbInformation, MB_OK);

Result := false
end;
发帖
68
金钱
0
威望
0
只看该作者 4 发表于: 2005-02-24
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Serv-U]
"Type"=dword:00000010
"Start"=dword:00000002
"ErrorControl"=dword:00000001
"ImagePath"=hex(2):43,00,3a,00,5c,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,\
20,00,46,00,69,00,6c,00,65,00,73,00,5c,00,53,00,65,00,72,00,76,00,2d,00,55,\
00,5c,00,53,00,65,00,72,00,76,00,55,00,44,00,61,00,65,00,6d,00,6f,00,6e,00,\
2e,00,65,00,78,00,65,00,00,00
"DisplayName"="Serv-U FTP 服务器"
"ObjectName"="LocalSystem"
"Description"="提供 FTP 服务并允许远程 FTP 客户连接到该计算机"
不在[合享网际],就在War3。
若两处都不在,我在去[合享网际]的路上...
离线aguangkj
发帖
49
金钱
0
威望
0
只看该作者 5 发表于: 2005-09-12
学习了
喜欢这里
离线iceshell
发帖
194
金钱
0
威望
0
只看该作者 6 发表于: 2005-09-16
学习 学习。。。
离线zhfi

发帖
461
金钱
190
威望
19
只看该作者 7 发表于: 2008-06-10
好东西,顶起来。
人生若只如初见@@一轩果

MyMPC 2013(104210239)
离线wfymqj

发帖
57
金钱
50
威望
5
只看该作者 8 发表于: 2008-06-11
有用,学习了
离线wchy
发帖
2
金钱
0
威望
0
只看该作者 9 发表于: 2010-03-18
good