Difference between revisions of "ServiceManager"

From Lazarus wiki
Jump to navigationJump to search
m (Text replace - "delphi>" to "syntaxhighlight>")
m (→‎Code example: Fix typo)
 
(14 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 +
{{Platform only|Windows|Windows|Windows}}
 +
{{ServiceManager}}
 +
 +
== ServiceManager ==
 
For Windows, the fcl-extra package contains a unit called ServiceManager.
 
For Windows, the fcl-extra package contains a unit called ServiceManager.
  
Example that checks whether the SamSs (Security Accounts Manager; should always be running) service is running is below.
+
The example below checks whether the SamSs (Security Accounts Manager; should always be running) service is running.
(Command line equivalent sc query samss).
+
(Command line equivalent <code>sc query samss</code>).
  
 +
=== Service Name ===
 +
Please note that if you develop your own service using the Lazdaemon package, the service name you must use is important. While the commands NET START and NET STOP use the service display name, the command SC and the code below use the service internal name. The display name is the one given to the property "DisplayName" of the item created in the DaemonDefs items. The service name is the property "Name" of the same item. The display name is the one currently displayed in the '''Name''' column by the MS services manager applet (services.msc)
 +
Let's use an example to clarify this. Assume you have written a service application called '''myService.exe''' in which there is one item in the DaemonDefs. The item has a name of "'''MyServ'''" and the associated "DisplayName" property has the value of "'''Internal build service'''". Using the command line as administrator you can:
  
<syntaxhighlight>program ServiceTest;
+
=== Service management using console ===
 +
 
 +
You will need:
 +
Microsoft .NET Framework 4.5.2 (Web Installer) for Windows Vista SP2, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2008 SP2 Windows Server 2008 R2 SP1, Windows Server 2012 and Windows Server 2012 R2
 +
 
 +
You have to get the support of .NET SDK Command prompt for install the service into your local machine.
 +
1. Call to SDK Command prompt, follow
 +
Start>All Programs>Microsoft .NET Framework SDK v2.0>SDK Command prompt
 +
 
 +
Install the service:
 +
<syntaxhighlight lang="dos">
 +
\your\path\to\application\myService.exe --install
 +
rem .... or /install, -install works too
 +
</syntaxhighlight>
 +
 
 +
Activate the service:
 +
In these commands, do not forget '''double quotes''' when multiple words are needed!
 +
<syntaxhighlight lang="dos">
 +
net start "Internal build service"
 +
rem .... or alternatively:
 +
sc start "MyServ"
 +
</syntaxhighlight>
 +
 
 +
To stop the service:
 +
<syntaxhighlight lang="dos">
 +
net stop '''"Internal build service"'''
 +
rem ... or alternatively
 +
sc stop "'''MyServ'''"
 +
</syntaxhighlight>
 +
 
 +
== Code example ==
 +
 
 +
Given the above, the code snippet to call the function below would be in our case:
 +
 
 +
<syntaxhighlight lang=pascal>
 +
if IsServiceRunning('MyServ') then
 +
</syntaxhighlight>
 +
 
 +
 
 +
Example program:
 +
<syntaxhighlight lang=pascal>program ServiceTest;
 
// Check if a certain process is running.
 
// Check if a certain process is running.
 
{$mode objfpc}{$H+}
 
{$mode objfpc}{$H+}
Line 30: Line 77:
 
       Services.Connect; //Now connect with requested access level
 
       Services.Connect; //Now connect with requested access level
 
       Services.GetServiceStatus(ServiceName, ServiceStatus);
 
       Services.GetServiceStatus(ServiceName, ServiceStatus);
       if ServiceStatus.dwCurrentState = SERVICE_RUNNING then
+
       Result := (ServiceStatus.dwCurrentState = SERVICE_RUNNING);
      begin
 
        Result := True;
 
      end
 
      else
 
      begin
 
        Result := False;
 
      end;
 
 
       Services.Disconnect;
 
       Services.Disconnect;
 
     except
 
     except
Line 43: Line 83:
 
       begin
 
       begin
 
         // A missing service might throw a missing handle exception? No?
 
         // A missing service might throw a missing handle exception? No?
      {LogOutput('Error getting service information for ' + ServiceName +
+
        {LogOutput('Error getting service information for ' + ServiceName +
        '. Technical details: ' + E.ClassName + '/' + E.Message);}
+
                  '. Technical details: ' + E.ClassName + '/' + E.Message); }
 
         Result := False;
 
         Result := False;
 
         raise; //rethrow original exception
 
         raise; //rethrow original exception
Line 50: Line 90:
 
       on E: Exception do
 
       on E: Exception do
 
       begin
 
       begin
      {LogOutput('Error getting service information for ' + ServiceName +
+
      {LogOutput('Error getting service information for ' + ServiceName +
        '. Technical details: ' + E.ClassName + '/' + E.Message);
+
                  '. Technical details: ' + E.ClassName + '/' + E.Message); }
        }
 
 
         Result := False;
 
         Result := False;
 
         raise; //rethrow original exception
 
         raise; //rethrow original exception
Line 69: Line 108:
 
   WriteLn('Starting test for ' + ServiceToTest + ' service.');
 
   WriteLn('Starting test for ' + ServiceToTest + ' service.');
 
   if IsServiceRunning(ServiceToTest) then
 
   if IsServiceRunning(ServiceToTest) then
  begin
+
     WriteLn('The ' + ServiceToTest + ' service is running')
     WriteLn('The ' + ServiceToTest + ' service is running');
 
  end
 
 
   else
 
   else
  begin
 
 
     WriteLn('The ' + ServiceToTest + ' service is not running');
 
     WriteLn('The ' + ServiceToTest + ' service is not running');
  end;
 
 
end.</syntaxhighlight>
 
end.</syntaxhighlight>
 +
 +
== See also ==
 +
* [[Daemons and Services]]
 +
* [[TServiceManager]]

Latest revision as of 08:31, 23 March 2022

Windows logo - 2012.svg

This article applies to Windows only.

See also: Multiplatform Programming Guide

English (en) español (es) polski (pl)

ServiceManager

For Windows, the fcl-extra package contains a unit called ServiceManager.

The example below checks whether the SamSs (Security Accounts Manager; should always be running) service is running. (Command line equivalent sc query samss).

Service Name

Please note that if you develop your own service using the Lazdaemon package, the service name you must use is important. While the commands NET START and NET STOP use the service display name, the command SC and the code below use the service internal name. The display name is the one given to the property "DisplayName" of the item created in the DaemonDefs items. The service name is the property "Name" of the same item. The display name is the one currently displayed in the Name column by the MS services manager applet (services.msc) Let's use an example to clarify this. Assume you have written a service application called myService.exe in which there is one item in the DaemonDefs. The item has a name of "MyServ" and the associated "DisplayName" property has the value of "Internal build service". Using the command line as administrator you can:

Service management using console

You will need: Microsoft .NET Framework 4.5.2 (Web Installer) for Windows Vista SP2, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2008 SP2 Windows Server 2008 R2 SP1, Windows Server 2012 and Windows Server 2012 R2

You have to get the support of .NET SDK Command prompt for install the service into your local machine. 1. Call to SDK Command prompt, follow Start>All Programs>Microsoft .NET Framework SDK v2.0>SDK Command prompt

Install the service:

\your\path\to\application\myService.exe --install 
rem .... or /install, -install works too

Activate the service: In these commands, do not forget double quotes when multiple words are needed!

net start "Internal build service"
rem .... or alternatively:
sc start "MyServ"

To stop the service:

net stop '''"Internal build service"'''
rem ... or alternatively 
sc stop "'''MyServ'''"

Code example

Given the above, the code snippet to call the function below would be in our case:

if IsServiceRunning('MyServ') then


Example program:

program ServiceTest;
// Check if a certain process is running.
{$mode objfpc}{$H+}
uses
  Classes,
  SysUtils,
  ServiceManager,
  JwaWinSvc {for services declarations};

function IsServiceRunning(ServiceName: string): boolean;
  {description Checks if a Windows service is running}
var
  Services: TServiceManager;
  ServiceStatus: TServiceStatus;
begin
  //Check for existing services
  //equivalent to sc query <servicename>
  Services := TServiceManager.Create(nil);
  try
    try
      Services.Acces := SC_MANAGER_CONNECT; //Note typo in property.
      //We don't need more access permissions than this; by default
      //the servicemanager is trying to get all access
      Services.Connect; //Now connect with requested access level
      Services.GetServiceStatus(ServiceName, ServiceStatus);
      Result := (ServiceStatus.dwCurrentState = SERVICE_RUNNING);
      Services.Disconnect;
    except
      on E: EServiceManager do
      begin
        // A missing service might throw a missing handle exception? No?
        {LogOutput('Error getting service information for ' + ServiceName +
                   '. Technical details: ' + E.ClassName + '/' + E.Message); }
        Result := False;
        raise; //rethrow original exception
      end;
      on E: Exception do
      begin
       {LogOutput('Error getting service information for ' + ServiceName +
                  '. Technical details: ' + E.ClassName + '/' + E.Message); }
        Result := False;
        raise; //rethrow original exception
      end;
    end;
  finally
    Services.Free;
  end;
end;

const
  ServiceToTest = 'SamSs';

//Security Accounts Manager, should be running, at least on Vista
begin
  WriteLn('Starting test for ' + ServiceToTest + ' service.');
  if IsServiceRunning(ServiceToTest) then
    WriteLn('The ' + ServiceToTest + ' service is running')
  else
    WriteLn('The ' + ServiceToTest + ' service is not running');
end.

See also