// myservice.h #include "ntservice.h" class CMyService : public CNTService { public: CMyService(); virtual BOOL OnInit(); virtual void Run(); virtual BOOL OnUserControl(DWORD dwOpcode); void SaveStatus(); // Control parameters int m_iStartParam; int m_iIncParam; // Current state int m_iState; };
正像你所看到的,CMyService 改寫了 CNTService 的 OnInit、Run 和 OnUserControl。它還有一個函數叫 SaveStatus,這個函數被用於將數據寫入注冊表,那些成員變量用來保存當前狀態。例子服務每隔一定的時間對一個整型變量進行增量處理。開始值和增量值都存在注冊表的參數中。這樣做並沒有別的意圖。只是為了簡單示范。下面我們看看這個服務是如何實現的。 實現 main 函數 有了從 CNTService 派生的 CMyService,實現 main 函數很簡單,請看 NTServApp.cpp 文件:
int main(int argc, char* argv[]) { // 創建服務對象 CMyService MyService; // 解析標准參數 (安裝, 卸載, 版本等.) if (!MyService.ParseStandardArgs(argc, argv)) { // 未發現任何標准參數,所以啟動服務, // 取消下面 DebugBreak 代碼行的注釋, // 當服務啟動後進入調試器, //DebugBreak(); MyService.StartService(); } // 到這裡,服務已經停止 return MyService.m_Status.dwWin32ExitCode; }這裡代碼不多,但執行後卻發生了很多事情,讓我們一步一步來看。首先,我們創建一個 MyService 類的實例。構造函數設置初始化狀態和服務名字(MyService.cpp):
CMyService::CMyService():CNTService("NT Service Demonstration") { m_iStartParam = 0; m_iIncParam = 1; m_iState = m_iStartParam; }
接著調用 ParseStandardArgs 檢查命令行是否包含服務安裝(-i)、卸載(-u)以及報告其版本號(-v)的請求。CNTService::ParseStandardArgs 分別調用 CNTService::IsInstalled,CNTService::Install 和 CNTService::Uninstall 來處理這些請求。如果沒有可識別的命令行參數,則假設該服務控制管理器試圖啟動該服務並調用 StartService。該函數直到服務停止運行才返回。當你調試完代碼,即可把用於調試的代碼行注釋掉或刪除。 安裝和卸載服務 服務的安裝由 CNTService::Install 處理,它用 Win32 服務管理器注冊服務並在注冊表中建立一個條目以支持服務運行時日志消息。 服務的卸載由 CNTService::Uninstall 處理,它僅僅通知服務管理器該服務已經不再需要。CNTService::Uninstall 不會刪除服務實際的可執行文件。 編寫服務代碼 現在我們來編寫實現服務的具體代碼。對於 NTService 例子,有三個函數要寫。他們涉及初始化,運行服務的細節和響應控制請求。 初始化 注冊表有一個給服務用來存儲參數的地方:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
我就是選擇這裡來存儲我的服務配置信息。我創建了一個 Parameters 鍵,並在此存儲我要保存的值。所以當服務啟動時,OnInit 函數被調用;這個函數從注冊表中讀取初始設置。