Solved

How can I tell what services are running

Posted on 2000-02-25
4
140 Views
Last Modified: 2010-04-04
How can I tell what NT services are running? I use D5 Ent.

Morten
0
Comment
Question by:mdrasted
[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
  • 2
4 Comments
 
LVL 10

Accepted Solution

by:
Lischke earned 200 total points
ID: 2558067
Hi Morten,

try this code to enumerate services:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Winsvc,
  StdCtrls, CheckLst;

type
  TForm1 = class(TForm)
    ServiceBox: TCheckListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ServiceBoxClickCheck(Sender: TObject);
  private
    FManager: SC_HANDLE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

var
  EnumStatus,
  Run: PEnumServiceStatus;
  S: PChar;
  BytesNeeded,
  Returned,
  Resume: DWORD;
  I: Integer;
  Service: SC_HANDLE;

begin
  FManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT or SC_MANAGER_ENUMERATE_SERVICE);
  if FManager = 0 then RaiseLastWin32Error
                  else
  begin
    Resume := 0;
    BytesNeeded := 0;
    EnumStatus := nil;
    // determine buffer size
    EnumServicesStatus(FManager, SERVICE_WIN32, SERVICE_ACTIVE or SERVICE_INACTIVE, EnumStatus^, 0,
                       BytesNeeded, Returned, Resume);
    if GetLastError = ERROR_MORE_DATA then
    begin
      GetMem(EnumStatus, BytesNeeded);
      EnumServicesStatus(FManager, SERVICE_WIN32, SERVICE_ACTIVE or SERVICE_INACTIVE, EnumStatus^, BytesNeeded,
                         BytesNeeded, Returned, Resume);
      Run := EnumStatus;
      for I := 0 to Returned - 1 do
      begin
        // add service to listbox
        with Run^ do
        begin
          S := AllocMem(StrLen(lpServiceName) + 1);
          Move(lpServiceName^, S^, StrLen(lpServiceName) + 1);
          ServiceBox.Items.AddObject(lpDisplayName, Pointer(S));

          // query running state
          Service := OpenService(FManager, lpServiceName, SERVICE_QUERY_STATUS);
          QueryServiceStatus(Service, ServiceStatus);
          if (ServiceStatus.dwCurrentState and SERVICE_RUNNING) <> 0 then ServiceBox.Checked[I] := True;
          CloseServiceHandle(Service);
        end;
        Inc(Run);
      end;
      FreeMem(EnumStatus);
    end;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);

var
  I: Integer;

begin
  for I := 0 to ServiceBox.Items.Count - 1 do
    FreeMem(Pointer(ServiceBox.Items.Objects[I]));
  if FManager <> 0 then CloseServiceHandle(FManager);
end;

procedure TForm1.ServiceBoxClickCheck(Sender: TObject);

var
  ServiceStatus: TServiceStatus;
  Service: SC_HANDLE;
  Dummy: PChar;
  Result: Boolean;

begin
  with ServiceBox do
  begin
    // state is already switched
    if not Checked[ItemIndex] then
    begin
      if MessageDlg('Do you want to stop this service?', mtConfirmation, [mbOK, mbCancel], 0) = mrOK then
      begin
        Service := OpenService(FManager, PChar(Items.Objects[ItemIndex]), SERVICE_STOP);
        if Service <> 0 then
        begin
          Result := ControlService(Service, SERVICE_CONTROL_STOP, ServiceStatus);
          CloseServiceHandle(Service);
          if not Result then
          begin
            Checked[ItemIndex] := True;
            RaiseLastWin32Error;
          end;
        end
        else
        begin
          Checked[ItemIndex] := True;
          RaiseLastWin32Error;
        end;
      end
      else
        Checked[ItemIndex] := True;
    end
    else
    begin
      if MessageDlg('Do you want to start this service?', mtConfirmation, [mbOK, mbCancel], 0) = mrOK then
      begin
        Service := OpenService(FManager, PChar(Items.Objects[ItemIndex]), SERVICE_START);
        if Service <> 0 then
        begin
          Dummy := nil;
          Result := StartService(Service, 0, Dummy);
          // check here periodically whether the service could be started
          CloseServiceHandle(Service);
          if not Result then
          begin
            Checked[ItemIndex] := False;
            RaiseLastWin32Error;
          end;
        end
        else
        begin
          Checked[ItemIndex] := False;
          RaiseLastWin32Error;
        end;
      end
      else
        Checked[ItemIndex] := False;
    end;
  end;
end;

end.


Open a new project and place a check list box on the main form. Name it "ServiceBox" and try it out.

Notes:
- I have not included the validation loops after starting and stopping a service, so wait a few seconds before you try to stop a service after you have started it with this code
- this code works only under WinNT
- if you get exceptions then it is likely that access has been denied (e.g. I can start my RPC locator service with this code, but not stop it. This happens also with the control panel "Services", so this is not a failure in the code).
- for a more complete implementation you need additional code to pass start parameters (if any, on my system no service needs parameters) and dependency checks before shutting down or starting a service

Ciao, Mike
0
 
LVL 1

Author Comment

by:mdrasted
ID: 2558264
Hi Mike,

I'll get back to you monday.

Morten
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2558331
Okey, dokey, have a nice weekend.

Ciao, Mike
0
 
LVL 1

Author Comment

by:mdrasted
ID: 2567874
Hi again,

Thanks for helping me. Nice code.

Regards,
Morten
0

Featured Post

Ready to get started with anonymous questions?

It's easy! Check out this step-by-step guide for asking an anonymous question on Experts Exchange.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month8 days, 8 hours left to enroll

615 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