How to create (register) services?
This page contains the two examples of how to register (install) Windows services. They both produce the same result. The first example is based on TWmiMethod and TWmiConnection components from WmiSet component collection. These components cooperate to call the Create method of Win32_Service class to perform the task. Look at this method's description on MSDN web site to find the complete list of parameters and accepted values. The second example utilizes TNTServiceManager component from NTSet component collection. Read the NTSet help file for the description of its CreateService method. There are minor differences in the examples:
  • WmiSet components better handle the connection to the remote host. They use the WMI connection capabilities. NTSet components use "null session" method, which may fail if the current user already has a connection to destination host with different credentials.
  • NTSet components use pure API and work little bit faster.
The source code below creates and destroys the components on the fly, so these functions may be used in console type applications. With minor changes the functions may be adapted for UI-type apps.

Please note that service applications created with Delphi or C++Builder can register themselves. Simply run them with "/install" parameter. The provided code can registers any service application on a local or remote computer. It also assigns the service parameters that may be different from those specified at compile time.

How to register (install) services with WmiSet?  Download

program service_register_wmiset;
{$APPTYPE CONSOLE}
uses
  SysUtils, WmiMethod, WmiConnection;

const
  // see more constant definition at MSDN web site,
  // description of method Win32_Service.Create
  SERVICE_TYPE_OWN_PROCESS = 16;

var
  Connection: TWmiConnection;
  Method: TWmiMethod;
  s: string;
begin
  // setup: create components and link them together
  Connection := TWmiConnection.Create(nil);
  Method     := TWmiMethod.Create(nil);
  try
    Connection.ObjectPath  := 'Win32_Service';
    Method.WmiObjectSource := Connection;
    // uncomment this block if creating service on a remote host. 
    // Connection.MachineName := '10.8.26.54'; 
    // Connection.Credentials.UserName := 'MyDomain\MyUser'; 
    // Connection.Credentials.Password := 'MyPassword'; 

    Connection.Connected := true;
    Method.WmiMethodName := 'Create';
    with Method.InParams do
    begin
      ParamByName('Name').AsString := 'MyNewService';
      ParamByName('DisplayName').AsString := 'The test service app';
      ParamByName('PathName').AsString := 'c:\temp\dummy_service.exe';
      ParamByName('ServiceType').AsInteger := SERVICE_TYPE_OWN_PROCESS;
      ParamByName('StartMode').AsString := 'Manual';
      // assign more paremeters here as needed.
    end;

    if Method.Execute <> 0 then
    begin
      s := Method.LastWmiErrorDescription;
      if s = '' then s := 'Error '+ IntToStr(Method.LastWmiError);
      writeln(s);
    end else
    begin
      writeln('Service installed OK');
    end;

  finally;
    Connection.Free;
    Method.Free;
  end;
end.
How to register (install) services with NTSet?  Download

program service_register_ntset;
{$APPTYPE CONSOLE}

uses
  SysUtils, NTServiceMan, WinSvc;

var
  ServiceMan: TNTServiceManager;
begin
  ServiceMan := TNTServiceManager.Create(nil);
  try
    // uncomment this block if configuring service on a remote host.
    // Connection.LogonAs.UserName := 'MyDomain\MyUser'; 
    // Connection.LogonAs.Password := 'MyPassword'; 
    // vServiceMan.MachineName := '\\10.8.26.54'; 
    // if (ServiceMan.ConnectIPC <> 0) then 
    //   writeln('Warning: could not use the provided credentials.'); 

    try
      ServiceMan.ManagerAccess := SC_MANAGER_CREATE_SERVICE;
      ServiceMan.ActiveManager := true;
      ServiceMan.ServiceName   := 'MyNewService1';
      ServiceMan.DisplayName   := 'The test service app 1';
      ServiceMan.BinaryPathName := 'c:\temp\dummy_service.exe';
      ServiceMan.ServiceType   := [WIN32_OWN_PROCESS];
      ServiceMan.StartType     := DEMAND_START;
      // assign more paremeters here as needed. 

      ServiceMan.Createservice;
      writeln('Service configured OK');
    except
      on E: Exception do
        writeln('Error: ' + E.Message);
    end;
  finally
    ServiceMan.ActiveManager := false;
    ServiceMan.Free;
  end;
end.