NT Services List

Top  Previous  Next

1.

 

procedure FixServiceNames;

const

RKEY_SERVICES = 'SYSTEM\CurrentControlSet\Services';

RKEY_IMAGE_PATH = 'ImagePath';

RKEY_START = 'Start';

var

ExePathName: string;

ServiceNames: TStringList;

Reg: TRegistry;

i: Integer;

ServiceKey: string;

ImagePath: string;

StartType: Integer;

Component: TComponent;

SLIndex: Integer;

begin

ExePathName := ParamStr(0);

 

ServiceNames := TStringList.Create;

try

  Reg := TRegistry.Create(KEY_READ);

  try

    Reg.RootKey := HKEY_LOCAL_MACHINE;

 

    // Openen registry key with all the installed services.

    if Reg.OpenKeyReadOnly(RKEY_SERVICES) then

    begin

      // Read them all installed services.

      Reg.GetKeyNames(ServiceNames);

 

      // Remove Services whose ImagePath does not match this executable.

      for i := ServiceNames.Count - 1 downto 0 do

      begin

        ServiceKey := '\' + RKEY_SERVICES + '\' + ServiceNames[i];

        if Reg.OpenKeyReadOnly(ServiceKey) then

        begin

          ImagePath := Reg.ReadString(RKEY_IMAGE_PATH);

          if SamePath(ImagePath, ExePathName) then

          begin

            // Only read 'Start' after 'ImagePath', the other way round often fails, because all

            // services are read here and not all of them have a "start" key or it has a different datatype.

            StartType := Reg.ReadInteger(RKEY_START);

            if StartType <> SERVICE_DISABLED then

              Continue;

          end;

 

          ServiceNames.Delete(i);

        end;

      end;

    end;

  finally

    FreeAndNil(Reg);

  end;

 

  // ServiceNames now only contains enabled services using this executable.

  ServiceNames.Sort;  // Registry may give them sorted, but now we are sure.

 

  if ServiceNames.Count > 0 then

    for i := 0 to SvcMgr.Application.ComponentCount - 1 do

    begin

      Component := SvcMgr.Application.Components[i];

      if not ( Component is TService ) then

        Continue;

 

      // Find returns whether the string is found and reports through Index where it is (found) or

      // where it should be (not found).

      if ServiceNames.Find(Component.Name, SLIndex) then

        // Component.Name found, nothing to do

      else

        // Component.Name not found, check whether ServiceName at SLIndex starts with Component.Name.

        // If it does, replace Component.Name.

        if SameText(Component.Name, Copy(ServiceNames[SLIndex], 1, Length(Component.Name))) then

        begin

          Component.Name := ServiceNames[SLIndex];

        end

        else

          ; // Service no longer in executable?

    end;

finally

  FreeAndNil(ServiceNames);

end;

end;