欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
用 C++ 創(chuàng )建簡(jiǎn)單的 Win32 服務(wù)程序

用 C++ 創(chuàng )建簡(jiǎn)單的 Win32 服務(wù)程序

作者:Nigel Thomson(MSDN 技術(shù)組)
翻譯:Northxizang

原文出處:Creating a Simple Win32 Service in C++

下載 NTService 例子源代碼
下載 NTServCpl 例子源代碼
下載 NTServCtrl 例子源代碼

摘要

  本文描述如何用 Visual C++ 創(chuàng )建 Windows NT 服務(wù)程序。創(chuàng )建該服務(wù)僅用到一個(gè) C++ 類(lèi),這個(gè)類(lèi)提供服務(wù)與操作系統之間一個(gè)簡(jiǎn)單的接口。使用這個(gè)類(lèi)實(shí)現自己的服務(wù)非常簡(jiǎn)單,只要改寫(xiě)少數幾個(gè)基類(lèi)中的虛擬函數即可。在本文有三個(gè)源代碼參考例子:
  • NTService 是一個(gè)簡(jiǎn)單的 Win32 服務(wù),它就是用本文所描述的方法建立的;
  • NTServCpl 是一個(gè)控制面版程序,用來(lái)控制 NTService 服務(wù);
  • NTServCtrl 是一個(gè)獨立的程序例子,用它可以監控某個(gè) Win32 服務(wù);

簡(jiǎn)介

  Windows NT 中的服務(wù)實(shí)際上是一個(gè)程序,只要計算機操作系統一啟動(dòng),服務(wù)就可以運行其中。它不需要用戶(hù)登陸。服務(wù)程序是一種與用戶(hù)無(wú)關(guān)的任務(wù),比如目錄復制,進(jìn)程監控或網(wǎng)絡(luò )上供其它機器使用的服務(wù),比如 HTTP 協(xié)議支持。
  創(chuàng )建 Windows NT 服務(wù)程序并不是很難。但調試某個(gè)服務(wù)程序不是一件容易的事。就我自己而言,我喜歡用 Visual C++ 編寫(xiě)自己的 C++ 程序。大多數 Win32 服務(wù)都是用 C 寫(xiě)的,所以我覺(jué)得如果用某個(gè) C++ 類(lèi)來(lái)實(shí)現 Win32 服務(wù)的基本功能一定很有意思。有了這個(gè) C++ 類(lèi),誰(shuí)要想用 C++ 創(chuàng )建 Win32 服務(wù)就是一件很簡(jiǎn)單的事情了。我為此開(kāi)發(fā)了一個(gè) C++ 基類(lèi),用它作為編寫(xiě) Win32 服務(wù)的起點(diǎn)應該沒(méi)有什么大問(wèn)題。

創(chuàng )建服務(wù)程序除了編寫(xiě)服務(wù)代碼外,還必須做一些其它額外的編碼工作:
  • 在系統日志或應用程序日志中報告警告信息和出錯信息,不能用輸出到屏幕的方式,因為用戶(hù)根本就沒(méi)有登陸。
  • 服務(wù)程序的控制即可以通過(guò)單獨的應用程序,也可以通過(guò)控制面版程序。這取決于你的服務(wù)實(shí)現什么樣的通訊機制。
  • 從系統中安裝和卸載服務(wù)

  大多數服務(wù)程序都是使用一個(gè)安裝程序來(lái)安裝,而用另外一個(gè)程序來(lái)卸載。本文我將這些功能內建在服務(wù)程序自身當中,使之一體化,這樣只分發(fā)一個(gè).EXE文件即可。你可以從命令行直接運行服務(wù)程序,并且可以隨心所欲地安裝和卸載或報告其版本信息。NTService 支持下列的命令行參數:

  • -v, 報告服務(wù)的名字和版本號;
  • -i, 安裝服務(wù);
  • -u, 卸載服務(wù);

默認情況下,當系統啟動(dòng)該服務(wù)時(shí)沒(méi)有命令行參數傳遞。

創(chuàng )建應用程序框架

  我一直都是創(chuàng )建基于 MFC 的應用程序。當我剛接觸 Win32 服務(wù)程序時(shí),我先是用 Visual C++ AppWizard 創(chuàng )建一個(gè) SDI/MFC 程序。然后去掉其中的文檔和視圖類(lèi)、圖標以及其它一些無(wú)用的東西,只剩下框架。結果到最后什么都去掉了,包括主窗口(服務(wù)程序不能有這個(gè)東東),什么也沒(méi)有留下,非常愚蠢。我不得不 又回過(guò)頭到 AppWizard,并用單個(gè)的源文件創(chuàng )建控制臺程序,此源文件包含main 入口函數,我將這個(gè)文件命名為 NTServApp.cpp。我用此 cpp 擴展而不是用 C,因為我只想用C++ 來(lái)寫(xiě)程序,而不是直接用 C。稍后我們會(huì )討論該文件代碼實(shí)現。
  因為我想用 C++ 類(lèi)來(lái)構建服務(wù),所以我創(chuàng )建了 NTService.h 和 NTService.cpp 文件,用它們來(lái)實(shí)現 CNTService 基類(lèi)。我還創(chuàng )建了 MyService.h 和 MyService.cpp 文件用于實(shí)現自己的服務(wù)類(lèi)(CMyService),它派生于 CNTService。稍后我們會(huì )看到代碼。
  建立新工程時(shí),我喜歡盡快看到運行結果,所以我決定服務(wù)程序要做的第一件事情是建立一個(gè)系統應用程序日志記錄。借助這個(gè)日志記錄機制,我能跟蹤服務(wù)何時(shí)啟動(dòng), 何時(shí)停止等等。我還可以記錄服務(wù)中發(fā)生的任何出錯信息。創(chuàng )建這個(gè)日志記錄比我想象的要復雜得多。

建立日志記錄
  我想,既然日志文件是操作系統的一部分,那么肯定有應用程序編程接口(API)來(lái)支持建立日志記錄。所以我開(kāi)始搜索 MSDN CD,直到發(fā)現 ReportEvent 函數為止。如果你不熟悉這個(gè)函數,你可能會(huì )想,這個(gè)函數應該知道在哪個(gè)日志文件建立記錄,以及你想要插入的文本信息。沒(méi)錯,這都是它要做的事情,但是為了簡(jiǎn)化出錯信息的國際化,該函數有一個(gè)消息 ID 作為參數,并在你提供的消息表中查找消息。所以問(wèn)題無(wú)非是你想將什么消息放入日志,以及如何將這些消息添加到你的應用程序中,下面我們一步一步來(lái)做:

  1. 以 .MC 為擴展名創(chuàng )建一個(gè)包含消息描述的文本文件。我將它命名為 NTServMsg.mc。該文件的格式非常特別,具體細節參見(jiàn) Platform SDK 文檔;
  2. 針對你的源文件運行消息編譯器(mc.exe),默認情況下它創(chuàng )建名為 MSG00001.BIN 的輸出文件。編譯器還創(chuàng )建一個(gè)頭文件(在我的例子程序中,該頭文件是 NTServMsg.h)和一個(gè).RC 文件(NTServMsg.rc)。只要你修改工程的 .MC 文件就必須重復這一步,所以把工具加到 Visual C++ 的工具菜單里做起來(lái)會(huì )很方便;
  3. 為工程創(chuàng )建一個(gè) .RC 文件,將 WINDOWS.H 頭文件以及消息編譯器產(chǎn)生的 .RC 文件包含到其中;
  4. 在主工程頭文件中包含消息編譯器產(chǎn)生的頭文件,以便模塊可以存取符號消息名;

  下面讓我們仔細一下這些文件,以便弄明白你自己需要創(chuàng )建什么,以及消息編譯器要為你創(chuàng )建些什么。我們不用研究整個(gè)消息集,只要看看其中一二個(gè)如何工作的即可。下面是例子程序消息源文件 NTServMsg.mc 的第一部分:

MessageId=100SymbolicName=EVMSG_INSTALLEDLanguage=EnglishThe %1 service was installed..MessageId=SymbolicName=EVMSG_REMOVEDLanguage=EnglishThe %1 service was removed..MessageId=SymbolicName=EVMSG_NOTREMOVEDLanguage=EnglishThe %1 service could not be removed..

  每一條都有一個(gè)消息ID,如果不特別設置,那么 ID 的取值就是指其前面所賦的值。每一條還有一個(gè)代碼中使用的符號名,語(yǔ)言標示符以及消息文本。消息可以跨多個(gè)行,并用含有一個(gè)句號的單獨一行終止。
  消息編譯器輸出一個(gè)庫文件,該庫文件被用作應用程序的資源,此外還輸出兩個(gè)要在代碼中包含的文件。下面是我的 .RC 文件:

// NTServApp.rc#include <windows.h>// 包含由消息編譯器(MC)產(chǎn)生的消息表資源腳本#include "NTServMsg.rc"Here''s the .RC file the message compiler generated:LANGUAGE 0x9,0x11 11 MSG00001.bin

正像你所看到的,這些文件中內容不多!

消息編譯器產(chǎn)生的最后一個(gè)文件是你要包含到代碼中的頭文件,下面就是這個(gè)頭文件的部分內容:

[..........]//// MessageId: EVMSG_INSTALLED//// MessageText://// The %1 service was installed.//#define EVMSG_INSTALLED 0x00000064L//// MessageId: EVMSG_REMOVED//// MessageText://// The %1 service was removed.//#define EVMSG_REMOVED 0x00000065L[...........]

  你可能已經(jīng)注意到了有幾個(gè)消息包含參數替代項(如 %1)。讓我們看看將消息寫(xiě)入某個(gè)系統日志文件時(shí)如何在代碼中使用消息ID和參數替代項。以事件日志中記錄成功安裝信息的部分安裝代碼為例。也就是 CNTService::IsInstalled 函數部分:

[....]LogEvent(EVENTLOG_INFORMATION_TYPE, EVMSG_INSTALLED, m_szServiceName);[....]

LogEvent 是另一個(gè) CNTService 函數,它使用事件類(lèi)型(信息,警告或錯誤),事件消息的 ID,以及形成日志消息的最多三個(gè)參數的替代串:

// This function makes an entry into the application event log.void CNTService::LogEvent(WORD wType, DWORD dwID,const char* pszS1,const char* pszS2,const char* pszS3){const char* ps[3];ps[0] = pszS1;ps[1] = pszS2;ps[2] = pszS3;int iStr = 0;for (int i = 0; i < 3; i++) {if (ps[i] != NULL) iStr++;}// Check to see if the event source has been registered,// and if not then register it now.if (!m_hEventSource) {m_hEventSource = ::RegisterEventSource(NULL, // local machinem_szServiceName); // source name}if (m_hEventSource) {::ReportEvent(m_hEventSource,wType,0,dwID,NULL, // sidiStr,0,ps,NULL);}}		
如你所見(jiàn),其主要工作是由 ReportEvent 系統函數處理。

  至此,我們已經(jīng)可以通過(guò)調用 CNTService::LogEvent 在系統日志中記錄事件了。接下來(lái)我們將考慮創(chuàng )建服務(wù)本身的一些代碼。

編寫(xiě)服務(wù)代碼

  為了建構一個(gè)簡(jiǎn)單的 Win32 服務(wù),你需要知道的大多數信息都可以在 Platform SDK 中找到。其中的范例代碼都是用C語(yǔ)言寫(xiě)的,并且很好理解。我的 CNTService 類(lèi)就是基于這些代碼。

一個(gè)服務(wù)主要包括三個(gè)函數:
  • main函數,這是代碼的入口。我們正是在這里解析任何命令行參數并進(jìn)行服務(wù)的安裝,移除,啟動(dòng)等等。
  • 在例子中,提供真正服務(wù)代碼的入口函數叫 ServiceMain。你可以隨便叫它什么。在服務(wù)第一次啟動(dòng)的惡時(shí)候,將該函數的地址傳遞給服務(wù)管理器。
  • 處理來(lái)自服務(wù)管理器命令消息的函數。在例子中,這個(gè)函數叫 Handler,這個(gè)名字可以隨意取。

服務(wù)回調函數
  因為 ServiceMain 和 Handler 函數都是由系統來(lái)調用,所以它們必須遵循操作系統的參數傳遞規范和調用規范。也就是說(shuō),它們不能簡(jiǎn)單地作為某個(gè) C++ 類(lèi)的成員函數。這樣就給封裝帶來(lái)一些不便,因為我們想把 Win32 服務(wù)的功能封裝在一個(gè) C++ 類(lèi)中。為了解決這個(gè)問(wèn)題,我將 ServiceMain 和 Handler 函數創(chuàng )建成 CNTService 類(lèi)的靜態(tài)成員。這樣就使我得以創(chuàng )建可以由操作系統調用的函數。 但是,這樣做還沒(méi)有完全解決問(wèn)題,因為系統不允許給被調用的函數傳遞任何形式的用戶(hù)數據,所以我們無(wú)法確定對 C++ 對象特定實(shí)例的 ServiceMain 或 Handler 的調用。用了一個(gè)非常簡(jiǎn)單但有局限的方法來(lái)解決這個(gè)問(wèn)題。我創(chuàng )建一個(gè)包含 C++ 對象指針的靜態(tài)變量。這個(gè)變量是在該對象首次創(chuàng )建是進(jìn)行初始化的。這樣便限制你每個(gè)服務(wù)應用只有一個(gè)C++對象。我覺(jué)得這個(gè)限制并不過(guò)分。下面是 NTService.h 文件中的聲明:

class CNTService{[...]// 靜態(tài)數據static CNTService* m_pThis; // nasty hack to get object ptr[...]};

下面是初始化 m_pThis 指針的方法:

CNTService::CNTService(const char* szServiceName){// Copy the address of the current object so we can access it from// the static member callback functions.// WARNING: This limits the application to only one CNTService object.m_pThis = this;[...]}

CNTService 類(lèi)

  當我創(chuàng )建 C++ 對象封裝 Windows 函數時(shí),我嘗試為我封裝的每個(gè) Windows API 除了創(chuàng )建成員函數外,還做一些別的工作,我嘗試讓對象更容易使用,降低實(shí)現特定項目所需的代碼行數。因此我的對象是基于“我想讓這個(gè)對象做什么?”而不是“Windows 用這些 APIs 做什么?”
  CNTService 類(lèi)包含一些用來(lái)解析命令行的成員函數,為了處理服務(wù)的安裝和拆卸以及事件日志的記錄,你得在派生類(lèi)中重寫(xiě)一些虛擬函數來(lái)處理服務(wù)控制管理器的請求。下面我們將通過(guò)本文的例子服務(wù)實(shí)現來(lái)研究這些函數的使用。
  如果你想創(chuàng )建盡可能簡(jiǎn)單的服務(wù),只需要重寫(xiě) CNTService::Run 即可,它是你編寫(xiě)代碼實(shí)現具體服務(wù)任務(wù)的地方。你還需要實(shí)現 main 函數。如果服務(wù)需要實(shí)現一些初始化。如從注冊表讀取數據,還需重寫(xiě) CNTService::OnInit。如果你要向服務(wù)發(fā)送命令消息 ,那么可以在服務(wù)中使用系統函數 ControlService,重寫(xiě) CNTService::OnUserControl 來(lái)處理請求。

在例子應用程序中使用 CNTService
  NTService 在 CMyService 類(lèi)中實(shí)現了它的大多數功能,CMyService 由 CNTService 派生。 MyService.h 頭文件如下:

// 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 parametersint m_iStartParam;int m_iIncParam;// Current stateint m_iState;};

  正像你所看到的,CMyService 改寫(xiě)了 CNTService 的 OnInit、Run 和 OnUserControl。它還有一個(gè)函數叫 SaveStatus,這個(gè)函數被用于將數據寫(xiě)入注冊表,那些成員變量用來(lái)保存當前狀態(tài)。例子服務(wù)每隔一定的時(shí)間對一個(gè)整型變量進(jìn)行增量處理。開(kāi)始值和增量值都存在注冊表的參數中。這樣做并沒(méi)有別的意圖。只是為了簡(jiǎn)單示范。下面我們看看這個(gè)服務(wù)是如何實(shí)現的。

實(shí)現 main 函數

有了從 CNTService 派生的 CMyService,實(shí)現 main 函數很簡(jiǎn)單,請看 NTServApp.cpp 文件:

int main(int argc, char* argv[]){// 創(chuàng  )建服務(wù)對象CMyService MyService;// 解析標準參數 (安裝, 卸載, 版本等.)if (!MyService.ParseStandardArgs(argc, argv)) {// 未發(fā)現任何標準參數,所以啟動(dòng)服務(wù),// 取消下面 DebugBreak 代碼行的注釋?zhuān)?/ 當服務(wù)啟動(dòng)后進(jìn)入調試器,//DebugBreak();MyService.StartService();}// 到這里,服務(wù)已經(jīng)停止return MyService.m_Status.dwWin32ExitCode;}		
  這里代碼不多,但執行后卻發(fā)生了很多事情,讓我們一步一步來(lái)看。首先,我們創(chuàng )建一個(gè) MyService 類(lèi)的實(shí)例。構造函數設置初始化狀態(tài)和服務(wù)名字(MyService.cpp):
CMyService::CMyService():CNTService("NT Service Demonstration"){m_iStartParam = 0;m_iIncParam = 1;m_iState = m_iStartParam;}

  接著(zhù)調用 ParseStandardArgs 檢查命令行是否包含服務(wù)安裝(-i)、卸載(-u)以及報告其版本號(-v)的請求。CNTService::ParseStandardArgs 分別調用 CNTService::IsInstalled,CNTService::Install 和 CNTService::Uninstall 來(lái)處理這些請求。如果沒(méi)有可識別的命令行參數,則假設該服務(wù)控制管理器試圖啟動(dòng)該服務(wù)并調用 StartService。該函數直到服務(wù)停止運行才返回。當你調試完代碼,即可把用于調試的代碼行注釋掉或刪除。

安裝和卸載服務(wù)
  服務(wù)的安裝由 CNTService::Install 處理,它用 Win32 服務(wù)管理器注冊服務(wù)并在注冊表中建立一個(gè)條目以支持服務(wù)運行時(shí)日志消息。
  服務(wù)的卸載由 CNTService::Uninstall 處理,它僅僅通知服務(wù)管理器該服務(wù)已經(jīng)不再需要。CNTService::Uninstall 不會(huì )刪除服務(wù)實(shí)際的可執行文件。

編寫(xiě)服務(wù)代碼

  現在我們來(lái)編寫(xiě)實(shí)現服務(wù)的具體代碼。對于 NTService 例子,有三個(gè)函數要寫(xiě)。他們涉及初始化,運行服務(wù)的細節和響應控制請求。

初始化
  注冊表有一個(gè)給服務(wù)用來(lái)存儲參數的地方:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

  我就是選擇這里來(lái)存儲我的服務(wù)配置信息。我創(chuàng )建了一個(gè) Parameters 鍵,并在此存儲我要保存的值。所以當服務(wù)啟動(dòng)時(shí),OnInit 函數被調用;這個(gè)函數從注冊表中讀取初始設置。

BOOL CMyService::OnInit(){// Read the registry parameters.// Try opening the registry key:// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\ParametersHKEY hkey;char szKey[1024];strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\");strcat(szKey, m_szServiceName);strcat(szKey, "\\Parameters");if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,szKey,0,KEY_QUERY_VALUE,&hkey) == ERROR_SUCCESS) {// Yes we are installed.DWORD dwType = 0;DWORD dwSize = sizeof(m_iStartParam);RegQueryValueEx(hkey,"Start",NULL,&dwType,(BYTE*)&m_iStartParam,&dwSize);dwSize = sizeof(m_iIncParam);RegQueryValueEx(hkey,"Inc",NULL,&dwType,(BYTE*)&m_iIncParam,&dwSize);RegCloseKey(hkey);}// Set the initial state.m_iState = m_iStartParam;return TRUE;}		
現在我們有了服務(wù)參數,我們便可以運行服務(wù)了。

運行服務(wù)
當 Run 函數被調用時(shí)將執行服務(wù)的主體代碼。本文例子的這部分很簡(jiǎn)單:
void CMyService::Run(){while (m_bIsRunning) {// Sleep for a while.DebugMsg("My service is sleeping (%lu)...", m_iState);Sleep(1000);// Update the current state.m_iState += m_iIncParam;}}		
  注意,只要服務(wù)不終止,這個(gè)函數就不會(huì )退出。當有終止服務(wù)的請求時(shí),CNTService::m_bIsRunning 標志被置成 FALSE。如果在服務(wù)終止時(shí),你要實(shí)現清除操作,那么你還可以改寫(xiě) OnStop 和/或 OnShutdown。

響應控制請求
  你可以用任何適合的方式與服務(wù)通訊——命名管道,思想交流,便條等等——對于一些簡(jiǎn)單的請求,用系統函數 ControlService 很容易實(shí)現。CNTService 提供了一個(gè)處理器專(zhuān)門(mén)用于通過(guò) ControlService 函數發(fā)送的非標準消息(也就是用戶(hù)發(fā)送的消息)。本文例子用單一消息在注冊表中保存當前服務(wù)的狀態(tài),以便其它應用程序能看到它。我不建議用這種方法來(lái)監控服務(wù),因為它不是最佳方法,這只是比較容易編碼實(shí)現而已。ControlService 所能處理的用戶(hù)消息必須在 128 到 255 這個(gè)范圍。我定義了一個(gè)常量 SERVICE_CONTROL_USER,128 作為基值。范圍內的用戶(hù)消息被發(fā)送到 CNTService:: OnUserControl,在例子服務(wù)中,處理此消息的細節如下:
BOOL CMyService::OnUserControl(DWORD dwOpcode){switch (dwOpcode) {case SERVICE_CONTROL_USER + 0:// Save the current status in the registry.SaveStatus();return TRUE;default:break;}return FALSE;   // say not handled}		
SaveStatus 是一個(gè)局部函數,用來(lái)在注冊表中存儲服務(wù)狀態(tài)。

調試 Win32 服務(wù)

  main 函數中包含一個(gè)對 DebugBreak 的調用,當服務(wù)第一次被啟動(dòng)時(shí),它會(huì )激活系統調試器。你可以監控來(lái)自調試器命令窗口中的服務(wù)調試信息。你可以在服務(wù)中用 CNTService::DebugMsg 來(lái)報告調試期間感興趣的事件。
  為了調試服務(wù)代碼,你需要按照 Platform SDK 文檔中的要求安裝 系統調試器(WinDbg)。你也可以用 Visual Studio 自帶的調試器調試 Win32 服務(wù)。
  有一點(diǎn)很重要,那就是 當它被服務(wù)管理器控制時(shí),你不能終止服務(wù)和單步執行,因為服務(wù)管理器會(huì )讓服務(wù)請求 超時(shí)并終止服務(wù)線(xiàn)程。所以你只能讓服務(wù)吐出消息,跟蹤其過(guò)程并在調試器窗口查看它們。
  當服務(wù)啟動(dòng)后(例如,從控制面板的“服務(wù)”中),調試器將在服務(wù)線(xiàn)程的掛起后啟動(dòng)。你需要通過(guò)單擊“Go”按鈕或按 F5 讓繼續運行。然后在調試器中觀(guān)察服務(wù)的運行過(guò)程。

下面是啟動(dòng)和終止服務(wù)的調試輸出例子:
Module Load: WinDebug/NTService.exe (symbol loading deferred)Thread Create: Process=0, Thread=0Module Load: C:\NT351\system32\NTDLL.DLL (symbol loading deferred)Module Load: C:\NT351\system32\KERNEL32.DLL (symbol loading deferred)Module Load: C:\NT351\system32\ADVAPI32.DLL (symbol loading deferred)Module Load: C:\NT351\system32\RPCRT4.DLL (symbol loading deferred)Thread Create: Process=0, Thread=1*** WARNING: symbols checksum is wrong 0x0005830f 0x0005224f for C:\NT351\symbols\dll\NTDLL.DBGModule Load: C:\NT351\symbols\dll\NTDLL.DBG (symbols loaded)Thread Terminate: Process=0, Thread=1, Exit Code=0Hard coded breakpoint hitHard coded breakpoint hit[](130): CNTService::CNTService()Module Load: C:\NT351\SYSTEM32\RPCLTC1.DLL (symbol loading deferred)[NT Service Demonstration](130): Calling StartServiceCtrlDispatcher()Thread Create: Process=0, Thread=2[NT Service Demonstration](174): Entering CNTService::ServiceMain()[NT Service Demonstration](174): Entering CNTService::Initialize()[NT Service Demonstration](174): CNTService::SetStatus(3026680, 2)[NT Service Demonstration](174): Sleeping...[NT Service Demonstration](174): CNTService::SetStatus(3026680, 4)[NT Service Demonstration](174): Entering CNTService::Run()[NT Service Demonstration](174): Sleeping...[NT Service Demonstration](174): Sleeping...[NT Service Demonstration](174): Sleeping...[NT Service Demonstration](130): CNTService::Handler(1)[NT Service Demonstration](130): Entering CNTService::Stop()[NT Service Demonstration](130): CNTService::SetStatus(3026680, 3)[NT Service Demonstration](130): Leaving CNTService::Stop()[NT Service Demonstration](130): Updating status (3026680, 3)[NT Service Demonstration](174): Leaving CNTService::Run()[NT Service Demonstration](174): Leaving CNTService::Initialize()[NT Service Demonstration](174): Leaving CNTService::ServiceMain()[NT Service Demonstration](174): CNTService::SetStatus(3026680, 1)Thread Terminate: Process=0, Thread=2, Exit Code=0[NT Service Demonstration](130): Returned from StartServiceCtrlDispatcher()Module Unload: WinDebug/NTService.exeModule Unload: C:\NT351\system32\NTDLL.DLLModule Unload: C:\NT351\system32\KERNEL32.DLLModule Unload: C:\NT351\system32\ADVAPI32.DLLModule Unload: C:\NT351\system32\RPCRT4.DLLModule Unload: C:\NT351\SYSTEM32\RPCLTC1.DLLThread Terminate: Process=0, Thread=0, Exit Code=0Process Terminate: Process=0, Exit Code=0>

總結

  也許用 C++ 創(chuàng )建 Win32 服務(wù)并不是最理想的,但使用單一的類(lèi)來(lái)派生你自己的服務(wù)的確方便了你的服務(wù)開(kāi)發(fā)工作。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
windows服務(wù)程序編寫(xiě) - C程序設計語(yǔ)言 - CUIT技術(shù)網(wǎng)[成都信息工程學(xué)院] CUIT最大的技術(shù)站點(diǎn)|編程開(kāi)發(fā),Linux,windows,網(wǎng)絡(luò )安全,internet使用,web,GIS,Robot,求職招聘 - Powered by Discuz!
編寫(xiě)有圖形界面的 Windows 服務(wù)程序 - VC知識庫文章
全面認識Svchost.exe進(jìn)程 - 電腦故障 - 360論壇
WINDOWS進(jìn)程祥解
共享軟件加密的一些誤區
手動(dòng)添加系統服務(wù)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久