unit ProjectInstaller;
//------------------------------------------------------------------------------
//  File name:      ProjectInstaller.pas
//  Last updated:   11/9/03
//  Author:         Sergey Mishkovskiy
//  Company:        USysWare, Inc.
//  Contact info:   usysware@comcast.net
//
//  Compatibility:  Borland Delphi for .NET
//
//  Description:    Consists of a TServiceInstaller class that encapsulates 
//                  .NET service installer functionality. When installing the 
//                  service, the install utility uses reflection to discover 
//                  all Installer class descendants that have RunInstaller 
//                  attribute set. It's important that installer's ServiceName 
//                  is kept in sync with service's ServiceName.
//------------------------------------------------------------------------------

interface

uses
  System.ServiceProcess,
  System.Configuration.Install,
  System.ComponentModel,
  System.Collections,
  Microsoft.Win32;

const
  DefaultServiceName = 'MyWindowsService';
  DefaultServiceDisplayName = 'My Windows Service';
  DefaultServiceDescription = 'This is my Windows service';

type
  [RunInstaller(True)]
  TServiceInstaller = class(System.Configuration.Install.Installer)
  private
    FServicesDependedOn: array of string;
    FServiceProcessInstaller: System.ServiceProcess.ServiceProcessInstaller;
    FServiceInstaller: System.ServiceProcess.ServiceInstaller;

    procedure AddServiceDescription(ServiceDesc: string);
  strict protected
    procedure OnBeforeInstall(savedState: IDictionary); override;
    procedure OnAfterInstall(savedState: IDictionary); override;
    procedure OnBeforeUninstall(savedState: IDictionary); override;
    procedure OnAfterUninstall(savedState: IDictionary); override;
  public
    constructor Create;
  end;

var
  // This is needed for Borland Delphi for .NET to emit TServiceInstaller class info
  ServiceInstaller: TServiceInstaller = nil;

implementation

{ TServiceInstaller }

constructor TServiceInstaller.Create;
begin
  inherited Create;

  //ToDo: add more service dependencies here
  SetLength(FServicesDependedOn, 1);
  FServicesDependedOn[0] := 'Event Log';

  FServiceProcessInstaller :=
    System.ServiceProcess.ServiceProcessInstaller.Create;
  FServiceProcessInstaller.Account :=
    System.ServiceProcess.ServiceAccount.LocalSystem;
  FServiceProcessInstaller.Password := '';
  FServiceProcessInstaller.Username := '';

  FServiceInstaller := System.ServiceProcess.ServiceInstaller.Create;
  FServiceInstaller.ServiceName := DefaultServiceName;
  FServiceInstaller.DisplayName := DefaultServiceDisplayName;
  //ToDo: adjust service type to Manual if necessary
  FServiceInstaller.StartType :=
    System.ServiceProcess.ServiceStartMode.Automatic;
  FServiceInstaller.ServicesDependedOn := FServicesDependedOn;

  Installers.Add(FServiceProcessInstaller);
  Installers.Add(FServiceInstaller);
end;

// Note that Description will be automatically deleted along with the
// service registry key when the service's uninstalled
procedure TServiceInstaller.AddServiceDescription(ServiceDesc: string);
var
  ServiceKey: RegistryKey;
begin
  try
    ServiceKey := Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
      'SYSTEM\CurrentControlSet\Services\' + DefaultServiceName, True);
  except
    ServiceKey := nil;
  end;

  if (ServiceKey <> nil) then
  begin
    try
      ServiceKey.SetValue('Description', ServiceDesc);
    except
    end;

    ServiceKey.Close;
  end;
end;

procedure TServiceInstaller.OnBeforeInstall(savedState: IDictionary);
begin
  //ToDo: add your code here

  inherited;
end;

procedure TServiceInstaller.OnAfterInstall(savedState: IDictionary);
begin
  inherited;

  AddServiceDescription(DefaultServiceDescription);
  
  //ToDo: add your code here
end;

procedure TServiceInstaller.OnBeforeUninstall(savedState: IDictionary);
begin
  //ToDo: add your code here

  inherited;
end;

procedure TServiceInstaller.OnAfterUninstall(savedState: IDictionary);
begin
  inherited;

  //ToDo: add your code here
end;

end.
