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

