----此例中原程序使用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的內容:
/************