Windows 服務(wù)被設(shè)計(jì)用于需要在后臺(tái)運(yùn)行的應(yīng)用程序以及實(shí)現(xiàn)沒(méi)有用戶交互的任務(wù)。為了學(xué)習(xí)這種控制臺(tái)應(yīng)用程序的基礎(chǔ)知識(shí),C(不是C++)是選擇。本文將建立并實(shí)現(xiàn)一個(gè)簡(jiǎn)單的服務(wù)程序,其功能是查詢系統(tǒng)中可用物理內(nèi)存數(shù)量,然后將結(jié)果寫(xiě)入一個(gè)文本文件。最后,你可以用所學(xué)知識(shí)編寫(xiě)自己的 Windows 服務(wù)。
當(dāng)初我寫(xiě)第一個(gè)NT 服務(wù)時(shí),我到 MSDN 上找例子。在那里我找到了一篇 Nigel Thompson 寫(xiě)的文章:“Creating a Simple Win32 Service in C++”,這篇文章附帶一個(gè) C++ 例子。雖然這篇文章很好地解釋了服務(wù)的開(kāi)發(fā)過(guò)程,但是,我仍然感覺(jué)缺少我需要的重要信息。我想理解通過(guò)什么框架,調(diào)用什么函數(shù),以及何時(shí)調(diào)用,但 C++ 在這方面沒(méi)有讓我輕松多少。面向?qū)ο蟮姆椒ü倘环奖?,但由于用類?duì)底層 Win32 函數(shù)調(diào)用進(jìn)行了封裝,它不利于學(xué)習(xí)服務(wù)程序的基本知識(shí)。這就是為什么我覺(jué)得 C 更加適合于編寫(xiě)初級(jí)服務(wù)程序或者實(shí)現(xiàn)簡(jiǎn)單后臺(tái)任務(wù)的服務(wù)。在你對(duì)服務(wù)程序有了充分透徹的理解之后,用 C++ 編寫(xiě)才能游刃有余。當(dāng)我離開(kāi)原來(lái)的工作崗位,不得不向另一個(gè)人轉(zhuǎn)移我的知識(shí)的時(shí)候,利用我用 C 所寫(xiě)的例子就非常容易解釋 NT 服務(wù)之所以然。
服務(wù)是一個(gè)運(yùn)行在后臺(tái)并實(shí)現(xiàn)勿需用戶交互的任務(wù)的控制臺(tái)程序。Windows NT/2000/XP 操作系統(tǒng)提供為服務(wù)程序提供專門(mén)的支持。人們可以用服務(wù)控制面板來(lái)配置安裝好的服務(wù)程序,也就是 Windows 2000/XP 控制面板 管理工具中的“服務(wù)”(或在“開(kāi)始” “運(yùn)行”對(duì)話框中輸入 services.msc /s——譯者注)??梢詫⒎?wù)配置成操作系統(tǒng)啟動(dòng)時(shí)自動(dòng)啟動(dòng),這樣你就不必每次再重啟系統(tǒng)后還要手動(dòng)啟動(dòng)服務(wù)。
本文將首先解釋如何創(chuàng)建一個(gè)定期查詢可用物理內(nèi)存并將結(jié)果寫(xiě)入某個(gè)文本文件的服務(wù)。然后指導(dǎo)你完成生成,安裝和實(shí)現(xiàn)服務(wù)的整個(gè)過(guò)程。
第一步:主函數(shù)和全局定義
首先,包含所需的頭文件。例子要調(diào)用 Win32 函數(shù)(windows.h)和磁盤(pán)文件寫(xiě)入(stdio.h):
#include
#include
接著,定義兩個(gè)常量:
#define SLEEP_TIME 5000
#define LOGFILE "C:MyServicesmemstatus.txt"
SLEEP_TIME 指定兩次連續(xù)查詢可用內(nèi)存之間的毫秒間隔。在第二步中編寫(xiě)服務(wù)工作循環(huán)的時(shí)候要使用該常量。
LOGFILE 定義日志文件的路徑,你將會(huì)用 WriteToLog 函數(shù)將內(nèi)存查詢的結(jié)果輸出到該文件,WriteToLog 函數(shù)定義如下:
int WriteToLog(char* str)
{
FILE* log;
log = fopen(LOGFILE, "a+");
if (log == NULL)
return -1;
fprintf(log, "%sn", str);
fclose(log);
return 0;
}
聲明幾個(gè)全局變量,以便在程序的多個(gè)函數(shù)之間共享它們值。此外,做一個(gè)函數(shù)的前向定義:
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
當(dāng)初我寫(xiě)第一個(gè)NT 服務(wù)時(shí),我到 MSDN 上找例子。在那里我找到了一篇 Nigel Thompson 寫(xiě)的文章:“Creating a Simple Win32 Service in C++”,這篇文章附帶一個(gè) C++ 例子。雖然這篇文章很好地解釋了服務(wù)的開(kāi)發(fā)過(guò)程,但是,我仍然感覺(jué)缺少我需要的重要信息。我想理解通過(guò)什么框架,調(diào)用什么函數(shù),以及何時(shí)調(diào)用,但 C++ 在這方面沒(méi)有讓我輕松多少。面向?qū)ο蟮姆椒ü倘环奖?,但由于用類?duì)底層 Win32 函數(shù)調(diào)用進(jìn)行了封裝,它不利于學(xué)習(xí)服務(wù)程序的基本知識(shí)。這就是為什么我覺(jué)得 C 更加適合于編寫(xiě)初級(jí)服務(wù)程序或者實(shí)現(xiàn)簡(jiǎn)單后臺(tái)任務(wù)的服務(wù)。在你對(duì)服務(wù)程序有了充分透徹的理解之后,用 C++ 編寫(xiě)才能游刃有余。當(dāng)我離開(kāi)原來(lái)的工作崗位,不得不向另一個(gè)人轉(zhuǎn)移我的知識(shí)的時(shí)候,利用我用 C 所寫(xiě)的例子就非常容易解釋 NT 服務(wù)之所以然。
服務(wù)是一個(gè)運(yùn)行在后臺(tái)并實(shí)現(xiàn)勿需用戶交互的任務(wù)的控制臺(tái)程序。Windows NT/2000/XP 操作系統(tǒng)提供為服務(wù)程序提供專門(mén)的支持。人們可以用服務(wù)控制面板來(lái)配置安裝好的服務(wù)程序,也就是 Windows 2000/XP 控制面板 管理工具中的“服務(wù)”(或在“開(kāi)始” “運(yùn)行”對(duì)話框中輸入 services.msc /s——譯者注)??梢詫⒎?wù)配置成操作系統(tǒng)啟動(dòng)時(shí)自動(dòng)啟動(dòng),這樣你就不必每次再重啟系統(tǒng)后還要手動(dòng)啟動(dòng)服務(wù)。
本文將首先解釋如何創(chuàng)建一個(gè)定期查詢可用物理內(nèi)存并將結(jié)果寫(xiě)入某個(gè)文本文件的服務(wù)。然后指導(dǎo)你完成生成,安裝和實(shí)現(xiàn)服務(wù)的整個(gè)過(guò)程。
第一步:主函數(shù)和全局定義
首先,包含所需的頭文件。例子要調(diào)用 Win32 函數(shù)(windows.h)和磁盤(pán)文件寫(xiě)入(stdio.h):
#include
#include
接著,定義兩個(gè)常量:
#define SLEEP_TIME 5000
#define LOGFILE "C:MyServicesmemstatus.txt"
SLEEP_TIME 指定兩次連續(xù)查詢可用內(nèi)存之間的毫秒間隔。在第二步中編寫(xiě)服務(wù)工作循環(huán)的時(shí)候要使用該常量。
LOGFILE 定義日志文件的路徑,你將會(huì)用 WriteToLog 函數(shù)將內(nèi)存查詢的結(jié)果輸出到該文件,WriteToLog 函數(shù)定義如下:
int WriteToLog(char* str)
{
FILE* log;
log = fopen(LOGFILE, "a+");
if (log == NULL)
return -1;
fprintf(log, "%sn", str);
fclose(log);
return 0;
}
聲明幾個(gè)全局變量,以便在程序的多個(gè)函數(shù)之間共享它們值。此外,做一個(gè)函數(shù)的前向定義:
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();

