首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

为什么 ControlService 老是失败!该怎么处理

2012-03-16 
为什么 ControlService 老是失败!//Windows服务的代码:unitUnit1interfaceusesWindows,Messages,SysUtils

为什么 ControlService 老是失败!
//Windows服务的代码:

unit   Unit1;

interface

uses
    Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   SvcMgr,   Dialogs;

const
    WM_SERVICE_TEST   =   WM_USER   +   299;

type
    TService1   =   class(TService)
    private
        {   Private   declarations   }
    protected
        function   DoCustomControl(CtrlCode:   DWord):   Boolean;   override;
    public
        function   GetServiceController:   TServiceController;   override;
        {   Public   declarations   }
    end;

var
    Service1:   TService1;

implementation

{$R   *.DFM}

procedure   ServiceController(CtrlCode:   DWord);   stdcall;
begin
    Service1.Controller(CtrlCode);
end;

function   TService1.DoCustomControl(CtrlCode:   DWord):   Boolean;
begin
    case   CtrlCode   of
        WM_SERVICE_TEST:
            begin
                MessageBox(0,   '测试服务自定义消息! ',   '测试 ',   MB_OK+MB_ICONINFORMATION);
            end;
    end;
    Result   :=   True;
end;

function   TService1.GetServiceController:   TServiceController;
begin
    Result   :=   ServiceController;
end;

end.


//测试应用程序:

unit   Unit1Exe;

interface

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

const
    WM_SERVICE_TEST   =   WM_USER   +   299;

type
    TForm1   =   class(TForm)
        Button1:   TButton;
        procedure   Button1Click(Sender:   TObject);
    private
        {   Private   declarations   }
    public
        {   Public   declarations   }
    end;

var
    Form1:   TForm1;

implementation

uses   SvcMgr,   WinSvc;

{$R   *.dfm}

procedure   TForm1.Button1Click(Sender:   TObject);
var
    MHnd,   SHnd:   SC_HANDLE;
    SerStatus:   _SERVICE_STATUS;
begin
    MHnd   :=   OpenSCManager( ' ',   nil,   SC_MANAGER_ALL_ACCESS);
    if   MHnd   <>   0   then
    try
        SHnd   :=   OpenService(MHnd,   PChar( 'Service1 '),   SERVICE_ALL_ACCESS);
        if   SHnd   <>   0   then
        try
            if   QueryServiceStatus(SHnd,   SerStatus)   then
                if   SerStatus.dwCurrentState   =   SERVICE_RUNNING   then


                    if   not   ControlService(SHnd,   WM_SERVICE_TEST,   SerStatus)   then
                        ShowMessage( '失败! ');
        finally
            CloseServiceHandle(SHnd);
        end;
    finally
        CloseServiceHandle(MHnd);
    end;
end;

end.

//为什么   ControlService   不能成功,老是提示失败!

[解决办法]
如果要自己定义服务的控制行为,需要override服务的DoCustomControl:

function TSvrXXXXX.DoCustomControl(CtrlCode: DWord): Boolean;

begin

Result := inherited DoCustomControl(CtrlCode);

case CtrlCode of

0:;

end;

end;

注意:CtrlCode的值必须大于128!

而外部的控制可以使用API函数ControlService来做:



function ServiceControl(const ServiceName: string; const ControlCode: integer;const Computer: PChar = nil): Boolean;

{

控制系统服务,可以指定代码: ControlCode 必须在 [128,255]

}

var

SCM, SCH: SC_Handle;

ServiceStatus: TServiceStatus;

begin

if IsLocalComputer(Computer) then

SCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS)

else

SCM := OpenSCManager(Computer, nil, SC_MANAGER_ALL_ACCESS);

if SCM <> 0 then

begin

SCH := OpenService(SCM, PChar(ServiceName), SERVICE_ALL_ACCESS);

if SCH <> 0 then

begin

Result := ControlService(SCH, ControlCode, ServiceStatus);

CloseServiceHandle(SCH);

end;

CloseServiceHandle(SCM);

end;

end;

需要注意的是,服务和控制部分的CtrlCode的定义必须一致!同时CtrolCode必须在128-255之间!

热点排行