delphi 如何检查指定服务的状态

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi 如何检查指定服务的状态相关的知识,希望对你有一定的参考价值。

我想写一个检查当现系统的服务状态程序.而后返回一个值!
最好能给我一个例子,谢谢!
例如:检查mysql和apache的服务状态!

如果满意在加100
什么东西呀...示例代码早看了!不明白呀!试了好久都不行!给个实例吧!

四楼的你好,我是做个本地的!那个代码我也看过,是一个SQL控件,不会用,
能不能帮我选出我要的~?只是检测当前的状态!OK,定给分!
谢谢~!

我写了一个函数在Windows XP SP2下测试通过,可以直接得到状态字符串

调用格式很简单,查看某服务状态的最简单方法:
ShowMessage(GetServiceStatusString('Brower'));
将显示Computer Browser服务的运行情况,Computer Browser服务的服务名称是Browser,还有Remote Procedure Call (RPC)服务的名字是RpcSs,Telnet的服务名称是TlntSvr等等

我没使用过mysql和apache服务,因此我无法知道他们的服务名字,但是你可以开始->运行->services.msc然后在服务列表中找到你要的服务,双击它,第一页的最上边就是服务名称,这是服务自己注册的名称,无论使用什么办法,还是要使用服务名称来区别服务

本函数得到是运行状态字符串,明白了程序原理的话,很容易将它转化成数字返回值,需要的话告诉我.函数是独立的,没有使用类库,不需要控件安装,其实就是API实现的,因此效率最高.

uses
  WinSvc; //引用此单元
 
function GetServiceStatusString(sServiceName: string): string;
var
  hService, hSCManager: SC_HANDLE;
  SS: TServiceStatus;
begin
  hSCManager := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  if hSCManager = 0 then
  begin
    result := 'Can not open the service control manager';
    exit;
  end;
  hService := OpenService(hSCManager, PChar(sServiceName), SERVICE_QUERY_STATUS);
  if hService = 0 then
  begin
    CloseServiceHandle(hSCManager);
    result := 'Can not open the service(' + sServiceName + ')';
    exit;
  end;
  if not QueryServiceStatus(hService, SS) then
    result := 'Can not query the service status'
  else
  begin
    case SS.dwCurrentState of
      SERVICE_CONTINUE_PENDING:
        result := 'The service(' + sServiceName + ') continue is pending';
      SERVICE_PAUSE_PENDING:
        result := 'The service(' + sServiceName + ') pause is pending.';
      SERVICE_PAUSED:
        result := 'The service(' + sServiceName + ') is paused.';
      SERVICE_RUNNING:
        result := 'The service(' + sServiceName + ') is running.';
      SERVICE_START_PENDING:
        result := 'The service(' + sServiceName + ') is starting.';
      SERVICE_STOP_PENDING:
        result := 'The service(' + sServiceName + ') is stopping.';
      SERVICE_STOPPED:
        result := 'The service(' + sServiceName + ') is not running.';
    else
      result := 'Unknown Status';
    end;
  end;
  CloseServiceHandle(hSCManager);
  CloseServiceHandle(hService);
end;
参考技术A 楼主:
我们先来明确一件事情:你的程序是要检查网络上别的机器上的服务器状态还是要检查本机上安装的服务程序状态?

武当之星的程序中QueryServiceStatus函数就是查询本机某服务程序的运行状况的函数,应该是一个WinAPI。TServiceManager就是Delphi中服务程序管理对象,可以直接使用GetStatus方法得到服务程序的运行状况。TserviceManager的使用方法可以参考:http://topic.csdn.net/t/20050809/15/4198321.html

如果是要查询网络上其他机器上的服务程序,就你提到的2个而言,可以尝试连接其默认端口,连接失败或超时则认为服务没有打开,否则认为服务已经打开并准备好服务。
==============================================
补充:现在我有事情,晚上有空给你个例子。
===============================================
再次补充:呵呵 天下有敌 已经抢先了,貌似可以,不过没有上机试过,楼主自己试试吧!
参考技术B 初学问题,...导出资料到Excel后时间格式无法重新设定,发现奇怪现像,哪位...我通过Adoquery1.NextRecordset(aRow)的方法取得了存储过程 参考技术C 是一段示例代码,自己看看;

unit ServiceManager;

interface

uses
SysUtils, Windows, WinSvc;

type

TServiceManager = class
private
Private declarations
ServiceControlManager: SC_Handle;
ServiceHandle: SC_Handle;
protected
function DoStartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
public
Public declarations
function Connect(MachineName: PChar = nil; DatabaseName: PChar = nil;
Access: DWORD = SC_MANAGER_ALL_ACCESS): Boolean; // Access may be SC_MANAGER_ALL_ACCESS
function OpenServiceConnection(ServiceName: PChar): Boolean;
function StartService: Boolean; overload; // Simple start
function StartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
overload; // More complex start
function StopService: Boolean;
procedure PauseService;
procedure ContinueService;
procedure ShutdownService;
procedure DisableService;
function GetStatus: DWORD;
function ServiceRunning: Boolean;
function ServiceStopped: Boolean;
end;

implementation

TServiceManager

function TServiceManager.Connect(MachineName, DatabaseName: PChar;
Access: DWORD): Boolean;
begin
Result := False;
open a connection to the windows service manager
ServiceControlManager := OpenSCManager(MachineName, DatabaseName, Access);
Result := (ServiceControlManager <> 0);
end;

function TServiceManager.OpenServiceConnection(ServiceName: PChar): Boolean;
begin
Result := False;
open a connetcion to a specific service
ServiceHandle := OpenService(ServiceControlManager, ServiceName, SERVICE_ALL_ACCESS);
Result := (ServiceHandle <> 0);
end;

procedure TServiceManager.PauseService;
var
ServiceStatus: TServiceStatus;
begin
Pause the service: attention not supported by all services
ControlService(ServiceHandle, SERVICE_CONTROL_PAUSE, ServiceStatus);
end;

function TServiceManager.StopService: Boolean;
var
ServiceStatus: TServiceStatus;
begin
Stop the service
Result := ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus);
end;

procedure TServiceManager.ContinueService;
var
ServiceStatus: TServiceStatus;
begin
Continue the service after a pause: attention not supported by all services
ControlService(ServiceHandle, SERVICE_CONTROL_CONTINUE, ServiceStatus);
end;

procedure TServiceManager.ShutdownService;
var
ServiceStatus: TServiceStatus;
begin
Shut service down: attention not supported by all services
ControlService(ServiceHandle, SERVICE_CONTROL_SHUTDOWN, ServiceStatus);
end;

function TServiceManager.StartService: Boolean;
begin
Result := DoStartService(0, '');
end;

function TServiceManager.StartService(NumberOfArgument: DWORD;
ServiceArgVectors: PChar): Boolean;
begin
Result := DoStartService(NumberOfArgument, ServiceArgVectors);
end;

function TServiceManager.GetStatus: DWORD;
var
ServiceStatus: TServiceStatus;
begin
Returns the status of the service. Maybe you want to check this
more than once, so just call this function again.
Results may be: SERVICE_STOPPED
SERVICE_START_PENDING
SERVICE_STOP_PENDING
SERVICE_RUNNING
SERVICE_CONTINUE_PENDING
SERVICE_PAUSE_PENDING
SERVICE_PAUSED
Result := 0;
QueryServiceStatus(ServiceHandle, ServiceStatus);
Result := ServiceStatus.dwCurrentState;
end;

procedure TServiceManager.DisableService;
begin
Implementation is following...
end;

function TServiceManager.ServiceRunning: Boolean;
begin
Result := (GetStatus = SERVICE_RUNNING);
end;

如何检查Apache Kafka服务运行状态

客户端应用程序使用Kafka主要分为两种类型,即生产者和消费者。无论哪种都需要kafka服务处于运行状态,本文介绍几种方法检查kafka服务器的运行状态。

使用Zookeeper 命令

检查活动的kafka服务的最快方法之一是使用zookeeper的dump命令。dump是管理zookeeper服务器的一个4LW命令。

现在我们使用nc命令发送dump给zookeeper服务器,默认为2181端口:

$ echo dump | nc localhost 2181 | grep -i broker | xargs
/brokers/ids/0

执行上面命令,可以在zookeeper上看到已注册的临时代理ID,如果没有临时id存在,则说明没有代理节点正在运行。
需要提醒的是,dump命令需要显示配置才允许执行。需要在 zookeeper.properties 或 zoo.cfg增加白名单命令列表:

lw.commands.whitelist=dump

当然也可以是使用Zookeeper APIs 查看活动代理服务器。

使用Apache kafka AdminClient

如果生产者和消费者是java应用程序,那么可以使用Apache Kafka AdminClent类检查kafka服务器是否处于运行状态。

下面首先定义KafkaAdminClient类包装AdminClient实例,这样我们就能够快速进行测试:

public class KafkaAdminClient 
    private final AdminClient client;

    public KafkaAdminClient(String bootstrap) 
        Properties props = new Properties();
        props.put("bootstrap.servers", bootstrap);
        props.put("request.timeout.ms", 3000);
        props.put("connections.max.idle.ms", 5000);

        this.client = AdminClient.create(props);
    

接下来在KafkaAdminClient类中定义verifyConnection() 方法验证客户端是否能连接上正在运行的kafka服务端:

public boolean verifyConnection() throws ExecutionException, InterruptedException 
    Collection<Node> nodes = this.client.describeCluster()
      .nodes()
      .get();
    return nodes != null && nodes.size() > 0;

最后通过连接kafka集群测试代码:

@Test
void givenKafkaIsRunning_whenCheckedForConnection_thenConnectionIsVerified() throws Exception 
    boolean alive = kafkaAdminClient.verifyConnection();
    assertThat(alive).isTrue();

使用kcat 工具

kcat,又称为 kafkacat,是一款非JVM的Kafka消息生产和消费的命令行工具,适用于 Kafka 0.8 及以上版本。ubuntu 上安装方式:

sudo apt-get update
sudo apt-get install kafkacat

可以通过kafkacat命令查看kafka服务运行状态,使用-L选项显示已经存在主题的元数据:

 kafkacat -b localhost:29092 -t demo-topic -L

Metadata for demo-topic (from broker -1: localhost:29092/bootstrap):
 3 brokers:
  broker 2 at localhost:29092
  broker 3 at localhost:39092
  broker 1 at localhost:19092
 1 topics:
  topic "demo-topic" with 0 partitions: Broker: Leader not available (try again)

从输出信息可以看到正在运行的kafka代理。

使用UI工具

对于开发环境的验证应用我们可以使用UI工具,如Offset Explorer,但这种方法不建议在生产环境使用。下面使用Offset Explorer连接kafka集群,输入zookeeper主机和端口:

我们能在左侧面板上看到正在运行的代理服务,点击节点可以查看更多细节。

总结

本文介绍了几种命令行方法:zookeeper命令、kafka的AdminClient、kcat工具以及UI方法查看kafka服务的运行状态。

以上是关于delphi 如何检查指定服务的状态的主要内容,如果未能解决你的问题,请参考以下文章

Delphi:如何创建到使用 DelphiMVCFramework 创建的 RESTful 服务器的有状态连接?

用Delphi开发一个程序,在服务端(受制端)锁屏状态下控制端如何实现监控和操作?

delphi 如何检测代理服务器是不是正常

delphi如何删除目录和目录下的所有文件

在Delphi开发的服务中调用指定应用程序

Delphi + Synapse:如何检查我是不是仍然连接