Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
unit winsvc2;
interface
uses winsvc, windows;
const
// A service started automatically by the service control manager during system startup.
SERVICE_AUTO_START = $00000002;
// A device driver started by the system loader. This value is valid only for driver services.
SERVICE_BOOT_START = $00000000;
//A service started by the service control manager when a process calls the StartService function.
SERVICE_DEMAND_START = $00000003;
//A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.
SERVICE_DISABLED = $00000004;
SERVICE_SYSTEM_START = $00000001;
SERVICE_KERNEL_DRIVER = $00000001;
SERVICE_FILE_SYSTEM_DRIVER = $00000002;
SERVICE_ADAPTER = $00000004;
SERVICE_RECOGNIZER_DRIVER = $00000008;
SERVICE_DRIVER =
(SERVICE_KERNEL_DRIVER or
SERVICE_FILE_SYSTEM_DRIVER or
SERVICE_RECOGNIZER_DRIVER);
SERVICE_WIN32_OWN_PROCESS = $00000010;
SERVICE_WIN32_SHARE_PROCESS = $00000020;
SERVICE_WIN32 =
(SERVICE_WIN32_OWN_PROCESS or
SERVICE_WIN32_SHARE_PROCESS);
SERVICE_INTERACTIVE_PROCESS = $00000100;
SERVICE_TYPE_ALL =
(SERVICE_WIN32 or
SERVICE_ADAPTER or
SERVICE_DRIVER or
SERVICE_INTERACTIVE_PROCESS);
// constants for QueryServiceConfig2
SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3;
SERVICE_CONFIG_DESCRIPTION = 1;
SERVICE_CONFIG_FAILURE_ACTIONS = 2;
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4;
SERVICE_CONFIG_PREFERRED_NODE = 9;
SERVICE_CONFIG_PRESHUTDOWN_INFO = 7;
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6;
SERVICE_CONFIG_SERVICE_SID_INFO = 5;
SERVICE_CONFIG_TRIGGER_INFO = 8;
type
// for QueryServiceConfig2, Description.
TSvcDescription = record
Length: DWord;
Desc: array[1..4096] of char;
end;
function ChangeServiceType(ServiceName: String; TypeID: DWord): Boolean;
function GetServiceStatus(ServiceName: String; ErrorState: Boolean): Boolean;
function StartService2(ServiceName: string): boolean;
function StopService(ServiceName: string): boolean;
function QueryServiceConfig2(hService: THandle; dwInfoLevel: DWord;
lpBuffer: Pointer; bufsize: DWord; var BytesNeeded: DWord): BOOL;
stdcall; external 'advapi32.dll' name 'QueryServiceConfig2A';
implementation
function ChangeServiceType(ServiceName: String; TypeID: DWord): Boolean;
// changes service type (eg Automatic, Manual, Disabled)
// returns true if service type successfully changed, false if a problem.
var
schandle: THandle;
scService: THandle;
begin
try
schandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
Result := (schandle <> 0);
if not Result then exit;
scService := OpenService(schandle, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
Result := (scService <> 0);
if not Result then exit;
Result := ChangeServiceConfig(scService, SERVICE_NO_CHANGE, TypeID,
SERVICE_NO_CHANGE, nil, nil, nil, nil, nil, nil, nil);
if not Result then exit;
finally
CloseServiceHandle(scService);
CloseServiceHandle(scHandle);
end;
end;
function GetServiceStatus(ServiceName: String; ErrorState: Boolean): Boolean;
// returns whether the specified service name is started or not.
// ErrorState is true or false based on error.
// Function return is true if service is started, false if service is stopped.
var
schandle: THandle;
scService: THandle;
ServiceStatus: TServiceStatus;
begin
try
Result := false;
schandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
ErrorState := (schandle = 0);
if ErrorState then exit;
scService := OpenService(schandle, PChar(ServiceName), SERVICE_ALL_ACCESS);
ErrorState := (scService = 0);
if ErrorState then exit;
ErrorState := not QueryServiceStatus(scService, ServiceStatus);
if ErrorState then exit;
if (ServiceStatus.dwCurrentState <> SERVICE_STOPPED) and
(ServiceStatus.dwCurrentState <> SERVICE_STOP_PENDING) then
Result := true
else
Result := false;
finally
CloseServiceHandle(scService);
CloseServiceHandle(scHandle);
end;
end;
function StartService2(ServiceName: string): boolean;
// starts service listed by service name.
// Result true if started, false if not for some reason
var
schandle: THandle;
scService: THandle;
ServiceStatus: TServiceStatus;
args: PChar;
begin
try
schandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
Result := (schandle = 0);
if Result then exit;
scService := OpenService(schandle, PChar(ServiceName), SERVICE_ALL_ACCESS);
Result := (scService = 0);
if Result then exit;
Result := QueryServiceStatus(scService, ServiceStatus);
if not Result then exit;
// if service is not stopped, don't bother trying to start it.
Result := (ServiceStatus.dwCurrentState = SERVICE_STOPPED);
if not Result then exit;
// now start service
args := nil;
Result := StartService(scService, 0, args);
if not Result then exit;
repeat
QueryServiceStatus(scService, ServiceStatus);
sleep(20);
until (ServiceStatus.dwCurrentState <> SERVICE_START_PENDING);
Result := (ServiceStatus.dwCurrentState = SERVICE_RUNNING);
finally
CloseServiceHandle(scService);
CloseServiceHandle(scHandle);
end;
end;
function StopDependentServices(scService: THandle): Boolean;
// stops all dependent services for the service handle given, no error checking
type
TSvcStatus = array[0..512] of TEnumServiceStatus;
PSvcStatus = ^TSvcStatus;
var
EnumRec: PSvcStatus;
bytesNeeded, numservices: integer;
i: integer;
begin
New(ENumRec);
Result := EnumDependentServices(scService, SERVICE_ACTIVE or SERVICE_INACTIVE, ENumRec^[0],
sizeof(TSvcStatus), BytesNeeded, numServices);
for i := 0 to NumServices-1 do
begin
StopService(String(ENumRec^[i].lpServiceName));
end;
Dispose(ENumRec);
end;
function StopService(ServiceName: string): boolean;
// stops service listed by service name.
// Result true if started, false if not for some reason
var
schandle: THandle;
scService: THandle;
ServiceStatus: TServiceStatus;
begin
try
schandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
Result := (schandle = 0);
if Result then exit;
scService := OpenService(schandle, PChar(ServiceName), SERVICE_ALL_ACCESS);
Result := (scService = 0);
if Result then exit;
Result := QueryServiceStatus(scService, ServiceStatus);
if not Result then exit;
// if service is not started, don't bother trying to start it.
Result := (ServiceStatus.dwCurrentState = SERVICE_RUNNING);
if not Result then exit;
// now stop service, starting with dependent services.
StopDependentServices(scService);
// Send a stop code to the service.
ControlService(scService, SERVICE_CONTROL_STOP, ServiceStatus);
if not Result then exit;
repeat
QueryServiceStatus(scService, ServiceStatus);
sleep(20);
until (ServiceStatus.dwCurrentState <> SERVICE_STOP_PENDING);
Result := (ServiceStatus.dwCurrentState = SERVICE_STOPPED);
finally
CloseServiceHandle(scService);
CloseServiceHandle(scHandle);
end;
end;
end.
var
ServiceName: string;
ServiceName := 'wuauserv'; // the Automatic Updates service.
ChangeServiceType(ServiceName, SERVICE_DISABLED); // disable
ChangeServiceType(ServiceName, SERVICE_DEMAND_START); // manual start
ChangeServiceType(ServiceName, SERVICE_AUTO_START); // automatic start
// start a service by name
if StartService2(ServiceName) then
ShowMessage('Service Is Started')
else
ShowMessage('Service Is Not Started For Some Reason');
// stop a service by name.
if StopService(ServiceName) then
ShowMessage('Service Is Stopped')
else
ShowMessage('Service Is Not Stopped For Some Reason');
procedure TForm1.Button6Click(Sender: TObject);
{ lists service infos into Memo1. Should produce the entire list of information that is available in the Windows service applet }
type
TSvcStatus = array[0..512] of TEnumServiceStatus;
PSvcStatus = ^TSvcStatus;
var
ScHandle: THandle;
lpServices: PSvcStatus;
BytesNeeded, ServicesReturned, ResumeHandle: DWord;
i: integer;
svcHandle: THandle;
ServiceConfig: TQueryServiceConfig;
SvcDesc: TSvcDescription;
begin
Memo1.Clear;
schandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
// Result := (schandle <> 0);
ResumeHandle := 0;
New(lpServices);
try
ENumServicesStatus(ScHandle, SERVICE_WIN32,
SERVICE_ACTIVE or SERVICE_INACTIVE, lpServices^[0], Sizeof(lpServices^),
BytesNeeded, ServicesReturned, ResumeHandle);
for i := 0 to ServicesReturned-1 do
with lpServices^[i] do
begin
Memo1.Lines.Add('Display Name: ' + String(lpDisplayName));
Memo1.Lines.Add('System Name: ' + String(lpServiceName));
case ServiceStatus.dwCurrentState of
SERVICE_STOPPED: Memo1.Lines.Add('Status: Stopped');
SERVICE_START_PENDING: Memo1.Lines.Add('Status: Startup Pending');
SERVICE_STOP_PENDING: Memo1.Lines.Add('Status: Stop Pending');
SERVICE_RUNNING: Memo1.Lines.Add('Status: Running');
SERVICE_CONTINUE_PENDING: Memo1.Lines.Add('Status: Continue Pending');
SERVICE_PAUSE_PENDING: Memo1.Lines.Add('Status: Pause Pending');
SERVICE_PAUSED: Memo1.Lines.Add('Status: Paused');
else
Memo1.Lines.Add('Status: Unknown');
end;
svcHandle := OpenService(ScHandle, lpServiceName, SERVICE_ALL_ACCESS);
QueryServiceConfig(svcHandle, ServiceConfig, Sizeof(ServiceConfig), bytesNeeded);
case ServiceConfig.dwStartType of
SERVICE_AUTO_START: Memo1.Lines.Add('Startup Type: Auto Start');
SERVICE_BOOT_START: Memo1.Lines.Add('Startup Type: Boot Start');
SERVICE_DEMAND_START: Memo1.Lines.Add('Startup Type: Manual');
SERVICE_DISABLED: Memo1.Lines.Add('Startup Type: Disabled');
SERVICE_SYSTEM_START: Memo1.Lines.Add('Startup Type: Automatic');
else
Memo1.Lines.Add('Startup Type: Unknown');
end;
QueryServiceConfig2(svcHandle, SERVICE_CONFIG_DESCRIPTION, @SvcDesc, Sizeof(SvcDesc), bytesNeeded);
CloseServiceHandle(svcHandle);
Memo1.Lines.Add('Description: ' + String(SvcDesc.Desc));
Memo1.Lines.Add('');
Memo1.Lines.Add('');
end;
finally
Dispose(lpservices);
CloseServiceHandle(ScHandle);
end;
end;