[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Services, List | Start/Stop

Posted on 2003-11-29
3
Medium Priority
?
384 Views
Last Modified: 2010-04-05
Hey All,

I need a simple program to list the services on a system
and two buttons,
"Start" //Starts selected service
"Stop" //Stops the selected service

Thanks, -Karamja-
0
Comment
Question by:-Karamja-
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 11

Accepted Solution

by:
shaneholmes earned 80 total points
ID: 9843341
See the code below to enumerate all running services. To see an example
of enumerating all running processes, download the JCL from
http://delphi-jedi.org/codelibjcl and look at the JclSysInfo unit (it
amounts to using either ToolHelp32 or PSAPI).


type
  LPENUM_SERVICE_STATUSW = ^ENUM_SERVICE_STATUSW;
  {$EXTERNALSYM LPENUM_SERVICE_STATUSW}
  _ENUM_SERVICE_STATUSW = record
    lpServiceName: LPWSTR;
    lpDisplayName: LPWSTR;
    ServiceStatus: SERVICE_STATUS;
  end;
  {$EXTERNALSYM _ENUM_SERVICE_STATUSW}
  ENUM_SERVICE_STATUSW = _ENUM_SERVICE_STATUSW;
  {$EXTERNALSYM ENUM_SERVICE_STATUSW}
  TEnumServiceStatusW = ENUM_SERVICE_STATUSW;
  PEnumServiceStatusW = LPENUM_SERVICE_STATUSW;

  LPSERVICE_STATUS_PROCESS = ^SERVICE_STATUS_PROCESS;
  {$EXTERNALSYM LPSERVICE_STATUS_PROCESS}
  _SERVICE_STATUS_PROCESS = record
    dwServiceType: DWORD;
    dwCurrentState: DWORD;
    dwControlsAccepted: DWORD;
    dwWin32ExitCode: DWORD;
    dwServiceSpecificExitCode: DWORD;
    dwCheckPoint: DWORD;
    dwWaitHint: DWORD;
    dwProcessId: DWORD;
    dwServiceFlags: DWORD;
  end;
  {$EXTERNALSYM _SERVICE_STATUS_PROCESS}
  SERVICE_STATUS_PROCESS = _SERVICE_STATUS_PROCESS;
  {$EXTERNALSYM SERVICE_STATUS_PROCESS}
  TServiceStatusProcess = SERVICE_STATUS_PROCESS;
  PServiceStatusProcess = LPSERVICE_STATUS_PROCESS;

  LPENUM_SERVICE_STATUS_PROCESSW = ^ENUM_SERVICE_STATUS_PROCESSW;
  {$EXTERNALSYM LPENUM_SERVICE_STATUS_PROCESSW}
  _ENUM_SERVICE_STATUS_PROCESSW = record
    lpServiceName: LPWSTR;
    lpDisplayName: LPWSTR;
    ServiceStatusProcess: SERVICE_STATUS_PROCESS;
  end;
  {$EXTERNALSYM _ENUM_SERVICE_STATUS_PROCESSW}
  ENUM_SERVICE_STATUS_PROCESSW = _ENUM_SERVICE_STATUS_PROCESSW;
  {$EXTERNALSYM ENUM_SERVICE_STATUS_PROCESSW}
  TEnumServiceStatusProcessW = ENUM_SERVICE_STATUS_PROCESSW;
  PEnumServiceStatusProcessW = LPENUM_SERVICE_STATUS_PROCESSW;

  _SC_ENUM_TYPE = (SC_ENUM_PROCESS_INFO);
  {$EXTERNALSYM _SC_ENUM_TYPE}
  SC_ENUM_TYPE = _SC_ENUM_TYPE;
  {$EXTERNALSYM SC_ENUM_TYPE}

function EnumServicesStatusW(hSCManager: SC_HANDLE; dwServiceType:
DWORD;
  dwServiceState: DWORD; lpServices: LPENUM_SERVICE_STATUSW; cbBufSize:
DWORD;
  var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD): BOOL;
stdcall;
  external advapi32 name 'EnumServicesStatusW';
{$EXTERNALSYM EnumServicesStatusW}

function EnumServicesStatusExW(hSCManager: SC_HANDLE; InfoLevel:
SC_ENUM_TYPE;
  dwServiceType: DWORD; dwServiceState: DWORD; lpServices: PByte;
  cbBufSize: DWORD; var pcbBytesNeeded, lpServicesReturned,
lpResumeHandle: DWORD;
  pszGroupName: LPCWSTR): BOOL; stdcall; external advapi32 name
'EnumServicesStatusExW';
{$EXTERNALSYM EnumServicesStatusExW}

// this one works only on Win2K up

procedure BuildServicesListEx(const List: TStrings);
var
  SCM: SC_HANDLE;
  Services, Service: PEnumServiceStatusProcessW;
  I: Integer;
  BufSize, BytesNeeded, ServiceCount, ResumeHandle: Cardinal;
begin
  Services := nil;
  SCM := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);
  if SCM <> 0 then
  try
    BufSize := 0;
    ResumeHandle := 0;
    while not EnumServicesStatusExW(SCM, SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
      SERVICE_ACTIVE, PByte(Services), BufSize, BytesNeeded,
ServiceCount,
      ResumeHandle, nil) do
    begin
      if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError;
      ReallocMem(Services, BytesNeeded);
      BufSize := BytesNeeded;
    end;
    Service := Services;
    for I := 0 to ServiceCount - 1 do
    begin
      List.Add(Service.lpServiceName);
      Inc(Service);
    end;
  finally
    FreeMem(Services);
    CloseServiceHandle(SCM);
  end;
end;

// this one works for WinNT 3.5 up

procedure BuildServicesList(const List: TStrings);
var
  SCM: SC_HANDLE;
  Services, Service: PEnumServiceStatusW;
  I: Integer;
  BufSize, BytesNeeded, ServiceCount, ResumeHandle: Cardinal;
begin
  Services := nil;
  SCM := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);
  if SCM <> 0 then
  try
    BufSize := 0;
    ResumeHandle := 0;
    while not EnumServicesStatusW(SCM, SERVICE_WIN32, SERVICE_ACTIVE,
      Services, BufSize, BytesNeeded, ServiceCount, ResumeHandle) do
    begin
      if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError;
      ReallocMem(Services, BytesNeeded);
      BufSize := BytesNeeded;
    end;
    Service := Services;
    for I := 0 to ServiceCount - 1 do
    begin
      List.Add(Service.lpServiceName);
      Inc(Service);
    end;
  finally
    FreeMem(Services);
    CloseServiceHandle(SCM);
  end;
end;
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 9843357
Now you will have to add two listboxes in your application which you can pass the returned TStrings too. Then you can create two buttons to start and stop the selected service depending on which item you select from the Listboxes.

procedure StartServiceExecute(Sender: TObject);
Var
  SCH: SC_HANDLE;
  SvcSCH: SC_HANDLE;
  arg: PChar;
begin
  SCH:= OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  If SCH=0 then
  Begin
    MessageDlg('Error: OpenSCManager', mtError, [mbOK], 0);
    Exit;
  End;

  Screen.Cursor:= crHourGlass;
  try
    SvcSCH:= OpenService(SCH, PChar(ServerServiceName), SERVICE_ALL_ACCESS);
    If SvcSCH=0 then
    Begin
      MessageDlg('Error: OpenService', mtError, [mbOK], 0);
      Exit;
    End;

    try
      arg:= nil;
      If Not StartService(SvcSCH, 0, arg) then
      Begin
        Case GetLastError of
          ERROR_ACCESS_DENIED              :MessageDlg('The specified handle
was not opened with SERVICE_START access.', mtError, [mbOK], 0);
          ERROR_INVALID_HANDLE             :MessageDlg('The specified handle
is invalid.', mtError, [mbOK], 0);
          ERROR_PATH_NOT_FOUND             :MessageDlg('The service binary
file could not be found.', mtError, [mbOK], 0);
          ERROR_SERVICE_ALREADY_RUNNING    :MessageDlg('An instance of the
service is already running.', mtError, [mbOK], 0);
          ERROR_SERVICE_DATABASE_LOCKED    :MessageDlg('The database is
locked.', mtError, [mbOK], 0);
          ERROR_SERVICE_DEPENDENCY_DELETED :MessageDlg('The service depends
on a service that does not exist or has been marked for deletion.', mtError,
[mbOK], 0);
          ERROR_SERVICE_DEPENDENCY_FAIL    :MessageDlg('The service depends
on another service that has failed to start.', mtError, [mbOK], 0);
          ERROR_SERVICE_DISABLED           :MessageDlg('The service has been
disabled.', mtError, [mbOK], 0);
          ERROR_SERVICE_LOGON_FAILED       :MessageDlg('The service could
not be logged on. This error occurs if the service was started from an
account that does not have the "Log on as a service" right.', mtError,
[mbOK], 0);
          ERROR_SERVICE_MARKED_FOR_DELETE  :MessageDlg('The service has been
marked for deletion.', mtError, [mbOK], 0);
          ERROR_SERVICE_NO_THREAD          :MessageDlg('A thread could not
be created for the service.', mtError, [mbOK], 0);
          ERROR_SERVICE_REQUEST_TIMEOUT    :MessageDlg('The process for the
service was started, but it did not call StartServiceCtrlDispatcher, or the
thread that called StartServiceCtrlDispatcher may be blocked in a control
handler function.', mtError, [mbOK], 0);
          Else                              MessageDlg('Error:
StartService', mtError, [mbOK], 0);
        End;{CASE}
      End;
      CheckServiceState;
    finally
      CloseServiceHandle(SvcSCH);
    end;
  finally
    Screen.Cursor:= crDefault;
    CloseServiceHandle(SCH);
  end;
end;

procedure StopServiceExecute(Sender: TObject);
Var
  SCH: SC_HANDLE;
  SvcSCH: SC_HANDLE;
  ss: TServiceStatus;
begin
  SCH:= OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  If SCH=0 then
  Begin
    MessageDlg('Error: OpenSCManager', mtError, [mbOK], 0);
    Exit;
  End;

  Screen.Cursor:= crHourGlass;
  try
    SvcSCH:= OpenService(SCH, PChar(ServerServiceName), SERVICE_ALL_ACCESS);
    If SvcSCH=0 then
    Begin
      MessageDlg('Error: OpenService', mtError, [mbOK], 0);
      Exit;
    End;

    try
      If Not ControlService(SvcSCH, SERVICE_CONTROL_STOP, ss) then
      Begin
        Case GetLastError of
          ERROR_ACCESS_DENIED               :MessageDlg('The specified
handle was not opened with the necessary access.', mtError, [mbOK], 0);
          ERROR_DEPENDENT_SERVICES_RUNNING  :MessageDlg('The service cannot
be stopped because other running services are dependent on it.', mtError,
[mbOK], 0);
          ERROR_INVALID_HANDLE              :MessageDlg('The specified
handle was not obtained using CreateService or OpenService, or the handle is
no longer valid.', mtError, [mbOK], 0);
          ERROR_INVALID_PARAMETER           :MessageDlg('The requested
control code is undefined.', mtError, [mbOK], 0);
          ERROR_INVALID_SERVICE_CONTROL     :MessageDlg('The requested
control code is not valid, or it is unacceptable to the service.', mtError,
[mbOK], 0);
          ERROR_SERVICE_CANNOT_ACCEPT_CTRL  :MessageDlg('The requested
control code cannot be sent to the service because the state of the service
is SERVICE_STOPPED, SERVICE_START_PENDING, or SERVICE_STOP_PENDING.',
mtError, [mbOK], 0);
          ERROR_SERVICE_NOT_ACTIVE          :MessageDlg('The service has not
been started.', mtError, [mbOK], 0);
          ERROR_SERVICE_REQUEST_TIMEOUT     :MessageDlg('The process for the
service was started, but it did not call StartServiceCtrlDispatcher, or the
thread that called StartServiceCtrlDispatcher may be blocked in a control
handler function.', mtError, [mbOK], 0);
          ERROR_SHUTDOWN_IN_PROGRESS        :MessageDlg('The system is
shutting down.', mtError, [mbOK], 0);
          Else                               MessageDlg('Error:
ControlService', mtError, [mbOK], 0);
        End;
      End;
      CheckServiceState;
    finally
      CloseServiceHandle(SvcSCH);
    end;
  finally
    Screen.Cursor:= crDefault;
    CloseServiceHandle(SCH);
  end;
end;
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 9843450
Thanks your your post,
But I cant get the code to work can you upload this to a webserver?
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question