程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> WindowsNT下Service編程

WindowsNT下Service編程

編輯:關於C++

----此例中原程序使用Delphi編制,老妖將之改成CB版。:D

----WindowsNTServer提供多種功能強大的服務(Service),例如FTP,WWW或遠程登錄服務,另外常用的數據庫服務器也是以Service的形式存在於NTServer上的,如Sybase SQLServer For NT。Service一般在NT啟動時自動啟動,在NT關機時停止。但是有時用戶可能想手工啟動、暫停、停止某項Service,這就需要在控制面板中進行配置,對於不太熟悉NT的用戶來說比較困難;對於軟件開發人員,有時需要在軟件中訪問和操作某項Service,甚至可能需要開發新Service的提供給用戶使用。上面兩種情況都可以通過對Service的編程來解決。對Service的編程涉及到NT的內核,比較復雜且相關資料較少,給軟件開發人員帶來很多困難,筆者通過對WindowsNT的API的分析找到了相應的編程方法,再此介紹給大家。

----在WindowsNT下,各種Service都存在service control manager database中,因此我們可以通過對service control manager database進行操作來實現對Service的編程。下面介紹常用的函數:

1:SC_HANDLE OpenSCManager(LPCTSTR lpszMachineName,LPCTSTR lpszDatabaseName,DWORD fdwDesiredAccess);

----Open SCManager 函數打開指定計算機上的service control manager database。其中參數lpszMachineName指定計算機名,若為空則指定為本機。參數lpszDatabaseName指定要打開的service control manager database,默認為空。

----參數fdwDesiredAccess指定操作的權限,可以為下面取值之一

SC_MANAGER_ALL_ACCESS    //所有權限

SC_MANAGER_CONNECT      //允許連接service control manager

SC_MANAGER_CREATE_SERVICE  //允許創建服務對象並把它加入service control manager database

SC_MANAGER_ENUMERATE_SERVICE //允許枚舉service control manager database中的服務

SC_MANAGER_LOCK       //允許鎖住service control manager database

SC_MANAGER_QUERY_LOCK_STATUS //允許獲取servicecontrolmanagerdatabase的封鎖信息

----函數返回值:函數執行成功則返回一個指向service control manager database的句柄,失敗則返回NULL。

2:SC_HANDLE OpenService(SC_HANDLE schSCManager,LPCTSTR lpszServiceName,DWORD fdwDesiredAccess);

----OpenService函數打開指定的Service。

----其中參數schSCManager是指向service control manager database的句柄,由OpenSCManager函數返回。

----參數lpszServiceName要打開的服務的名字,注意大小寫。

----參數fdwDesiredAccess指定操作的權限,可以為下面取值之一

SERVICE_ALL_ACCESS      //所有權限

SERVICE_CHANGE_CONFIG     //允許更改服務的配置

SERVICE_ENUMERATE_DEPENDENTS //允許獲取依賴於該服務的其他服務

SERVICE_INTERROGATE      //允許立即獲取服務狀態

SERVICE_PAUSE_CONTINUE    //允許暫停和喚醒服務

SERVICE_QUERY_CONFIG      //允許獲取服務配置

SERVICE_QUERY_STATU      //允許通過訪問service control manager獲取服務狀態

SERVICE_START         //允許啟動服務

SERVICE_STOP          //允許停止服務

SERVICE_USER_DEFINE_CONTROL  //允許用戶指定特殊的服務控制碼

----函數返回值:函數執行成功則返回指向某項服務的句柄,失敗則返回NULL。

3:BOOL QueryServiceStatus(SC_HANDLE schService,LPSERVICE_STATUS lpssServiceStatus);

----QueryServiceStatus函數返回指定服務的當前狀態。

----其中參數schService是指向某項服務的句柄,由OpenService函數返回,且必須SERVICE_QUERY_STATUS的權限。

----參數lpssServiceStatus中存放返回的服務狀態信息,結構如下

typedefstruct_SERVICE_STATUS
{
   DWORD dwServiceType;    //服務類型
   DWORD dwCurrentState;    //當前狀態
   DWORD dwControlsAccepted;  //服務可接受的控制碼
   DWORD dwWin32ExitCode;    //Win32出錯代碼
   DWORD dwServiceSpecificExitCode;//服務出錯代碼
   DWORD dwCheckPoint;      //用於跟蹤服務長時間操作
   DWORD dwWaitHint;       //服務某一操作的最大允許時間,以毫秒為單位
}SERVICE_STATUS,*LPSERVICE_STATUS;

----函數返回值:函數執行成功則返回True,失敗則返回False。

4:BOOLStartService(SC_HANDLE schService,DWORD dwNumServiceArgs,LPCTSTR * lpszServiceArgs);

----StartService函數啟動指定的服務。

----其中參數schService是指向某項服務的句柄,由OpenService函數返回,且必須有SERVICE_START的權限。

----dwNumServiceArgs為啟動服務所需的參數的個數。

----lpszServiceArgs為啟動服務所需的參數。函數返回值:函數執行成功則返回True,失敗則返回False。

5:BOOL ControlService(SC_HANDLE hService,DWORD dwControl,LPSERVICE_STATUS lpServiceStatus);

----ControlService函數向Win32service發送控制碼。

----其中參數hService是指向某項服務的句柄,由OpenService函數返回。

----參數dwControl為控制碼,常用的有

SERVICE_CONTROL_STOP   //停止服務

SERVICE_CONTROL_PAUSE  //暫停服務

SERVICE_CONTROL_CONTINUE  //喚醒暫停的服務

SERVICE_CONTROL_INTERROGATE//刷新某服務的狀態

----參數lpServiceStatus指向SERVICE_STATUS結構,用於存放該服務最新的狀態信息。

----函數返回值:函數執行成功則返回True,失敗則返回False。

6:BOOL EnumServicesStatus(SC_HANDLE hSCManager,DWORD dwServiceType,DWORD dwServiceState,LPENUM_SERVICE_STATUS lpServices,DWORD cbBufSize,LPDWORD pcbBytesNeeded,LPDWORD lpServicesReturned,LPDWORD lpResumeHandle);

----EnumServicesStatus函數用於枚舉NT下存在的Service。

----其中參數hSCManager是指向service control manager database的句柄,由OpenSCManager函數返回,且必須有SC_MANAGER_ENUMERATE_SERVICE的權限。

----參數dwServiceType指定按服務的類型枚舉。

----參數dwServiceState指定按服務的狀態枚舉。

----參數lpServices指向ENUM_SERVICE_STATUS結構,用於存放返回的服務的名字和狀態信息。

----參數cbBufSize返回參數lpServices的長度,以字節為單位。

----參數pcbBytesNeeded返回獲取剩余的Service所需字節的個數。

----參數lpServicesReturned返回服務的個數。

----參數lpResumeHandle,當第一次調用時該參數為0,當該函數再次被調用以獲取另外的信息時,該參數表示下一個被讀的Service。

----函數返回值:函數執行成功則返回True,失敗則返回False。

----值得注意的是通常情況下該函數返回的結果為FALSE,我們可以調用GetLastError()來獲取進一步信息。因為一台機器上有多種服務存在,所以GetLastError()應為ERROR_MORE_DATA,此時應再次調用EnumServicesStatus函數以獲取正確的Service列表。

----下面有一個用Delphi編的一個程序例子,用其他開發工具如VC,VB也可實現。程序運行時,單擊按鈕Button1枚舉NT中的Service並顯示在列表框ListBox1中。在ListBox1選中某個Service,單擊按鈕Button2則啟動該Service,單擊按鈕Button3則停止該Service。

首先在Unit1.hpp中添加

#include <winsvc.hpp>

然後在Class Form1的Private中添加

SC_HANDLE hscmanager,hService;

TServiceStatus returnstatus;

以下是Unit1.cpp的內容:

/**************************************************************************
* 枚舉NT系統當服務並啟動或終止之。
* Edited by 黑山老妖
* 2002.8.9
****************************************************************************/
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DWORD BytesNeeded,serviceReturned,resumeHandle;
bool returnflag;
TEnumServiceStatus lpservice[100];
TEnumServiceStatus service;
DWORD i,bytes;
ListBox1->Items->Clear();
returnflag=false;
resumeHandle=0;
hscmanager=OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE);//打開service control manager database
if (hscmanager<0)
  {
  ShowMessage("無法打開service control manager database");
  return;
  }
returnflag=EnumServicesStatus(hscmanager,SERVICE_DRIVER,SERVICE_ACTIVE,&service,sizeof(service),&BytesNeeded,&serviceReturned,&resumeHandle);//枚舉Service
if(!returnflag&&GetLastError()==ERROR_MORE_DATA)
  {
  bytes=BytesNeeded+sizeof(TEnumServiceStatus);
  EnumServicesStatus(hscmanager,SERVICE_DRIVER,SERVICE_ACTIVE,&lpservice[0],bytes,&BytesNeeded,&serviceReturned,&resumeHandle);
  for(i=0;i<serviceReturned-1;i++)
   {
   ListBox1->Items->Add(lpservice[i].lpServiceName);
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int i;
for(i=0;i<ListBox1->Items->Count;i++)
  {
  if(ListBox1->Selected[i])
   {
   hService=OpenService(hscmanager,PChar(ListBox1->Items->Strings[i].c_str()),SERVICE_ALL_ACCESS);//打開該Service
   if(hService<0)
    {
    ShowMessage("無法打開該服務!");
    return;
    }
   QueryServiceStatus(hService,&returnstatus);//查看該Service的狀態
   if(returnstatus.dwCurrentState==SERVICE_STOPPED)//如果該Service已停止則啟動它
   //SERVICE_STOPPED==1,SERVICE_RUNNING==4 老妖注。
    {
    if(StartService(hService,0,NULL))
     ShowMessage("啟動成功!");
    else
     ShowMessage("無法啟動該服務!");
    }
   CloseServiceHandle(hService);//關閉該Service
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
int i;
for(i=0;i<ListBox1->Items->Count;i++)
  {
  if(ListBox1->Selected[i])
   {
   hService=OpenService(hscmanager,PChar(ListBox1->Items->Strings[i].c_str()),SERVICE_ALL_ACCESS);//打開該Service
   if(hService<0)
    {
    ShowMessage("無法打開該Service");
    return;
    }
   QueryServiceStatus(hService,&returnstatus);//查看該Service的狀態
   if(returnstatus.dwCurrentState==SERVICE_RUNNING) //如果該Service正在運行則停止它
    {
    if(ControlService(hService,SERVICE_CONTROL_STOP,&returnstatus))
     ShowMessage("成功停止!");
    else
     ShowMessage("無法停止該服務!");
    }
   CloseServiceHandle(hService);//關閉該Service
   }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseServiceHandle(hscmanager);//關閉service control manager database    
}
//---------------------------------------------------------------------------

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved