• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

DELPHI中对NT服务型程序的控制单元

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

 {*******************************************************************************

   XOtecExpress Visual Component Library Copyright (c) 2008 XOtec Studio.

   By: PengJunLi Build: 2008-05-24
   E-mail: [email protected]  [email protected]
   QQ:442801172  (陆岛工作室)

*******************************************************************************
}

unit xtSrvUnit;

interface

uses Windows, Messages,  SysUtils, Classes, Forms, WinSvc, SvcMgr;

const
  SM_BASE                      
= WM_USER + 1736;
  SM_INITIALIZE                
= SM_BASE + 1;
  SM_SHUTDOWN                  
= SM_BASE + 2;
  SM_BREAKWAIT                 
= SM_BASE + 5;
  SM_USERSINFOUPDATE           
= SM_BASE + 11;

type
  EServiceError 
= class(Exception);
  TxtServiceStatus 
= (ssUnknow, ssStopped, ssStartPending, ssStopPending, ssRuning, ssContinuePending, ssPausePending, ssPaused);

  
{ TxtServiceApplication }
  
  TxtServiceApplication 
= class(TServiceApplication)
  private
    FEventLogger: TEventLogger;
    
procedure OnExceptionHandler(Sender: TObject; E: Exception);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    
procedure Run; override;
    
procedure ContinueRun;
  
end;


function Application: TxtServiceApplication;

function ServerInstalling: Boolean;

function IsServerIsRuning(ServiceName: string): Boolean;

//取服务状态
function GetServiceStatus(ServiceName: string): TxtServiceStatus;
//服务是否正在运行
function IsServiceRuning(ServiceName: string): Boolean;
//服务是否已停止
function IsServiceStopped(ServiceName: string): Boolean;

//启动服务
function StartService(ServiceName: string): Boolean; overload; // Simple start
function StartService(ServiceName: string; NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;overload; // More complex start
//停止服务
function StopService(ServiceName: string): Boolean;
//暂停服务
function PauseService(ServiceName: string): Boolean;
//继续服务
function ContinueService(ServiceName: string): Boolean;
//关闭服务
function ShutdownService(ServiceName: string): Boolean;
//禁止服务启动
function DisableService(ServiceName: string): Boolean;

//服务是否已安装
function IsServiceInstalled(ServiceName: string): Boolean;
//安装服务
function InstallService(ServiceName, DisplayName, Filename: string; ServiceDescription: string=''): Boolean;
//反安装服务
function UnInstallService(ServiceName: string): Boolean;
//为服务程序添加描述
procedure ServiceUpdateDescription(const ServiceName, Description: string);

//取得系统中所有服务列表
function GetNtServiceList(sMachine: string; AList: TStrings): Boolean;

function InitServiceDesktop: boolean;
procedure DoneServiceDeskTop;

implementation

uses Registry;

const
  DefaultWindowStation         
= 'WinSta0';
  DefaultDesktop               
= 'Default';

var
  hwinstaSave: HWINSTA;
  hdeskSave: HDESK;
  hwinstaUser: HWINSTA;
  hdeskUser: HDESK;
  FContinueHandlingMessages: Boolean 
= true;

{ ServerInstalling }

function ServerInstalling: Boolean;
begin
  Result :
= FindCmdLineSwitch('INSTALL',['-','\','/'], True) or
            FindCmdLineSwitch(
'UNINSTALL',['-','\','/'], True);
end;

{ GetServiceStatus }

function GetServiceStatus(ServiceName: string): TxtServiceStatus;
var
  ServiceStatus: TServiceStatus;
  hSCManager, ServiceHandle: SC_Handle;
begin
  Result :
= ssUnknow;
  
if (Trim(ServiceName)=''then Exit;

  hSCManager :
= OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  
if hSCManager<>0 then
  
begin
    ServiceHandle :
= OpenService(hSCManager, PChar(ServiceName), SERVICE_QUERY_STATUS);
    
if ServiceHandle<>0 then
    
begin
      QueryServiceStatus(ServiceHandle, ServiceStatus);
      CloseServiceHandle(ServiceHandle);
    
end;
    CloseServiceHandle(hSCManager);
  
end;

  
case ServiceStatus.dwCurrentState of
    SERVICE_STOPPED         : Result :
= ssStopped;
    SERVICE_START_PENDING   : Result :
= ssStartPending;
    SERVICE_STOP_PENDING    : Result :
= ssStopPending;
    SERVICE_RUNNING         : Result :
= ssRuning;
    SERVICE_CONTINUE_PENDING: Result :
= ssContinuePending;
    SERVICE_PAUSE_PENDING   : Result :
= ssPausePending;
    SERVICE_PAUSED          : Result :
= ssPaused;
  
end;
end;

{ IsServiceRuning }

function IsServiceRuning(ServiceName: string): Boolean;
begin
  Result :
= (GetServiceStatus(ServiceName) = ssRuning);
end;

{ IsServiceStopped }

function IsServiceStopped(ServiceName: string): Boolean;
begin
  Result :
= (GetServiceStatus(ServiceName) = ssStopped);
end;

{ StartService }

function StartService(ServiceName: string): Boolean; overload; // Simple start
begin
  Result :
= StartService(ServiceName, 0nil);
end;

function StartService(ServiceName: string; NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;overload; // More complex start
var
  SCManager, hService: SC_HANDLE;
begin
   Result :
= False;
  
if (Trim(ServiceName)=''then Exit;
  
   SCManager :
= OpenSCManager(nilnil, SC_MANAGER_ALL_ACCESS);
   Result :
= SCManager <> 0;
   
if Result then
   try
     hService :
= OpenService(SCManager, PChar(ServiceName), SERVICE_ALL_ACCESS);
     Result :
= hService <> 0;
     
if (hService <> 0then
     try
       Result :
= WinSvc.StartService(hService, NumberOfArgument, PChar(ServiceArgVectors));
       
if not Result and (GetLastError = ERROR_SERVICE_ALREADY_RUNNING) then
         Result :
= True;
     finally
       CloseServiceHandle(hService);
     
end;
   finally
     CloseServiceHandle(SCManager);
   
end;
end;

function DoControlService(ServiceName: string; ControlFalg: Cardinal): Boolean;
var
  ServiceStatus: TServiceStatus;
  SCManager, hService: SC_HANDLE;
begin
  Result :
= False;
  
if (Trim(ServiceName)=''then Exit;

   SCManager :
= OpenSCManager(nilnil, SC_MANAGER_ALL_ACCESS);
  
if SCManager<>0 then
  
begin
     hService :
= OpenService(SCManager, PChar(ServiceName), SERVICE_ALL_ACCESS);
    
if hService<>0 then
    
begin
      Result :
= ControlService(hService, ControlFalg, ServiceStatus);
      CloseServiceHandle(hService);
    
end;
    CloseServiceHandle(SCManager);
  
end;
end;

{ StopService }

function StopService(ServiceName: string): Boolean;
begin
  Result :
= DoControlService(ServiceName, SERVICE_CONTROL_STOP);
end;
{ PauseService }

function PauseService(ServiceName: string): Boolean;
begin
  Result :
= DoControlService(ServiceName, SERVICE_CONTROL_PAUSE);
end;

{ ContinueService }

function ContinueService(ServiceName: string): Boolean;
begin
  Result :
= DoControlService(ServiceName, SERVICE_CONTROL_CONTINUE);
end;

{ ShutdownService }

function ShutdownService(ServiceName: string): Boolean;
begin
  Result :
= DoControlService(ServiceName, SERVICE_CONTROL_SHUTDOWN);
end;

{ DisableService }

function DisableService(ServiceName: string): Boolean;
var
  SCManager, ServiceHandle: SC_HANDLE;
begin
  Result :
= False;
  
if (Trim(ServiceName)=''then Exit;

  SCManager :
= OpenSCManager(nilnil, SC_MANAGER_ALL_ACCESS);
  
if SCManager<>0 then
  
begin
    ServiceHandle :
= OpenService(SCManager, PChar(ServiceName), SERVICE_CHANGE_CONFIG);
    
if ServiceHandle<>0 then
    
begin
      ChangeServiceConfig(ServiceHandle,
                          SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE,
                          
nilnilnilnilnilnilnil);
      CloseServiceHandle(ServiceHandle);
      Result :
= True;
    
end;
    CloseServiceHandle(SCManager);
  
end;
end;

{ InstallService }

function InstallService(ServiceName, DisplayName, Filename: string; ServiceDescription: string=''): Boolean;
var
  SCManager, ServiceHandle: SC_HANDLE;
begin
  Result :
= False;
  
if (Trim(ServiceName)=''and not FileExists(Filename) then Exit;
  
  SCManager :
= OpenSCManager(nilnil, SC_MANAGER_ALL_ACCESS);
  
if SCManager = 0 then Exit;
  
  try
    ServiceHandle :
= CreateService(SCManager, PChar(ServiceName), PChar(DisplayName),
                                   SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS 
or SERVICE_INTERACTIVE_PROCESS,
                                   SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, PChar(Filename),
                                   
nilnilnilnilnil);

    
if IsServiceInstalled(ServiceName) and (ServiceDescription<>''then
      ServiceUpdateDescription(ServiceName, ServiceDescription);
    CloseServiceHandle(ServiceHandle);
    Result :
= ServiceHandle<>0;
  finally
    CloseServiceHandle(SCManager);
  
end;
end;

{ UnInstallService }

function UnInstallService(ServiceName: string): Boolean;
var
  SCManager, ServiceHandle: SC_HANDLE;
begin
  Result :
= False;
  
if (Trim(ServiceName)=''then Exit;

  SCManager :
= OpenSCManager(nil,nil,GENERIC_WRITE);
  
if SCManager = 0 then Exit;
  try
    ServiceHandle :
= OpenService(SCManager, PChar(ServiceName), _DELETE);
    Result :
= DeleteService(ServiceHandle);
    CloseServiceHandle(ServiceHandle);
  finally
    CloseServiceHandle(SCManager);
  
end;
end;

procedure ServiceUpdateDescription(const ServiceName, Description: string);
var
  reg: TRegistry;
begin
  reg :
= TRegistry.Create;
  try
    
with reg do begin
      RootKey :
= HKEY_LOCAL_MACHINE;
      
if OpenKey('SYSTEM\CurrentControlSet\Services\' + ServiceName, False) then
      
begin
         WriteString(
'Description', Description);
         
end;
         CloseKey;
      
end;
   finally
     reg.Free;
   
end;
end;

{ IsServiceInstalled }

function IsServiceInstalled(ServiceName: string): Boolean;
var
  Mgr, Svc: Integer;
begin
  Result :
= False;
  
if (Trim(ServiceName)=''then Exit;

  Mgr :
= OpenSCManager(nilnil, SC_MANAGER_ALL_ACCESS);
  
if Mgr <> 0 then
  
begin
    Svc :
= OpenService(Mgr, PChar(ServiceName), SERVICE_ALL_ACCESS);
    Result :
= Svc <> 0;
    
if Result then
      CloseServiceHandle(Svc);
    CloseServiceHandle(Mgr);
  
end;
end;

{ IsServerIsRuning }

function IsServerIsRuning(ServiceName: string): Boolean;
begin
  Result :
= False;
  
  
if (Trim(ServiceName)<>''and not ServerInstalling then
  
begin
    CreateMutex(
nil, True, PChar(ServiceName + '_Mutex'));
    Result :
= GetLastError = ERROR_ALREADY_EXISTS;
  
end;
end;

function GetNtServiceList(sMachine: string; AList: TStrings): Boolean;
var
   i: integer;
   sName, sDisplay: string;
   SCManager: SC_Handle;
   nBytesNeeded, nServices, nResumeHandle: Cardinal;
   ServiceStatusRecs: 
array[0..511of TEnumServiceStatus;
begin
   Result :
= false;
   SCManager :
= OpenSCManager(PChar(sMachine), nil, SC_MANAGER_ALL_ACCESS);
   try
     
if (SCManager = 0then Exit;
     nResumeHandle :
= 0;
     
while True do
     
begin
       EnumServicesStatus(SCManager, SERVICE_WIN32, SERVICE_STATE_ALL, ServiceStatusRecs[
0], SizeOf(ServiceStatusRecs),
         nBytesNeeded, nServices, nResumeHandle);
         
       
for i := 0 to nServices - 1 do
       
begin
         sName :
= ServiceStatusRecs[i].lpServiceName;
         sName :
= StringReplace(sName, '=''?', [rfReplaceAll, rfIgnoreCase]);

         sDisplay :
= ServiceStatusRecs[i].lpDisplayName;
         sDisplay :
= StringReplace(sDisplay, '=''#13#10', [rfReplaceAll, rfIgnoreCase]);
         sDisplay :
= StringReplace(sDisplay, '=''#13', [rfReplaceAll, rfIgnoreCase]);
         sDisplay :
= StringReplace(sDisplay, '=''#10', [rfReplaceAll, rfIgnoreCase]);
         AList.Add(sName 
+ '=' + sDisplay);
       
end;
       
       
if nBytesNeeded = 0 then Break;
     
end;
     Result :
= True;
   finally
     CloseServiceHandle(SCManager);
   
end;
end;

{ InitServiceDesktop }

function InitServiceDesktop: boolean;
var
  dwThreadId: DWORD;
begin
  dwThreadId :
= GetCurrentThreadID;
  
// Ensure connection to service window station and desktop, and
  
// save their handles.
  hwinstaSave :
= GetProcessWindowStation;
  hdeskSave   :
= GetThreadDesktop(dwThreadId);


  hwinstaUser :
= OpenWindowStation(DefaultWindowStation, FALSE, MAXIMUM_ALLOWED);
  
if hwinstaUser = 0 then
  
begin
    OutputDebugString(PChar(
'OpenWindowStation failed' +  SysErrorMessage(GetLastError)));
    Result :
= false;
    exit;
  
end;

  
if not SetProcessWindowStation(hwinstaUser)  then
  
begin
    OutputDebugString(
'SetProcessWindowStation failed');
    Result :
= false;
    exit;
  
end;

  hdeskUser :
= OpenDesktop(DefaultDesktop, 0, FALSE, MAXIMUM_ALLOWED);
  
if hdeskUser = 0 then
  
begin
    OutputDebugString(
'OpenDesktop failed');
    SetProcessWindowStation(hwinstaSave);
    CloseWindowStation(hwinstaUser);
    Result :
= false;
    exit;
  
end;
  Result :
= SetThreadDesktop(hdeskUser);
  
if not Result then
    OutputDebugString(PChar(
'SetThreadDesktop' + SysErrorMessage(GetLastError)));
end;

{ DoneServiceDeskTop }

procedure DoneServiceDeskTop;
begin
  
// Restore window station and desktop.
  SetThreadDesktop(hdeskSave);
  SetProcessWindowStation(hwinstaSave);
  
if hwinstaUser <> 0 then
    CloseWindowStation(hwinstaUser);
  
if hdeskUser <> 0 then
    CloseDesktop(hdeskUser);
end;

{ TServiceStartThread }

type
  TServiceTableEntryArray 
= array of TServiceTableEntry;

  TServiceStartThread 
= class(TThread)
  private
    FServiceStartTable: TServiceTableEntryArray;
  protected
    
procedure DoTerminate; override;
    


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap