Search code examples
inno-setuppascalscript

Service with DependsOn is not being set correctly in Inno Setup via CreateService function


I'm creating an installer for my app with Inno Setup and as part of the install it needs to install several services. For that I'm using the following code:

Dependency := '';
if Depends then begin
  Dependency := 'DependencyServiceName';
end;

if not IsServiceInstalled(ServiceName) then begin
  if not InstallService(
           '"' + Path + '"', ServiceName, ServiceName, Description,
           SERVICE_WIN32_OWN_PROCESS, StartType, False, Dependency) then begin   
    Result := False;
    FailedSoExit('Failed to install the ' + Name + ' service.');
    Exit;
  end;
end;

The relevant method is:

function CreateService(
  hSCManager : HANDLE; lpServiceName, lpDisplayName : string;
  dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl: cardinal;
  lpBinaryPathName, lpLoadOrderGroup: String; lpdwTagId : cardinal;
  lpDependencies, lpServiceStartName, lpPassword :string): cardinal;
external '[email protected] stdcall';

function InstallService(
  FileName, ServiceName, DisplayName, Description : string;
  ServiceType, StartType : cardinal; Delayed : Boolean;
  Dependency: String) : 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, Dependency, '', '');
    if hService <> 0 then begin
      Result := true;
      // Win2K & WinXP supports additional description text for services
      if Description<> '' then
        RegWriteStringValue(HKLM, 'System\CurrentControlSet\Services\' + ServiceName, 'Description', Description);
      if Delayed then            
        RegWriteDWordValue(HKLM, 'System\CurrentControlSet\Services\' + ServiceName, 'DelayedAutostart', 1);
      CloseServiceHandle(hService)
    end;
    CloseServiceHandle(hSCM)
  end;
end;

This has always been working and even now when I run through the compiler everything works fine with Dependency having the right name. However, on the test machine I'm installing it on it now seems to add random stuff after it so DependsOn in the registry will look something like (where {installPath} is the path Inno Setup is installing it):

DependencyServiceName
£$%
)
{installPath}

This is obviously causing the services to fail to start as the 3 extra "dependencies" don't exist as services.

Any ideas what could be causing this?


Solution

  • As the documentation of CreateService says, the lpDependencies parameter needs to be "double null-terminated".

    So if your code ever worked, if was just by an accident.

    This should do:

    Dependency := Dependency + #0;