Windows 2000 引入強大的**服務**機制:隨系統啟動、無用戶登錄即運行、可遠程管理。本文從零構建一個標準 Win32 服務框架,封裝 OpenSCManager、CreateService、StartServiceCtrlDispatcher 等核心 API,提供可直接填充業務邏輯的服務模板代碼。
| API | 用途 | 關鍵參數 |
|---|---|---|
OpenSCManager | 打開服務控制管理器數據庫 | lpMachineName=NULL (本機), dwDesiredAccess=SC_MANAGER_ALL_ACCESS |
CreateService | 在 SCM 中創建服務記錄 | lpServiceName, lpDisplayName, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START |
StartServiceCtrlDispatcher | 連接 SCM,進入服務主循環 | 傳入 SERVICE_TABLE_ENTRY 陣列 (服務名+ServiceMain) |
RegisterServiceCtrlHandler | 註冊控制處理函數 | 返回 SERVICE_STATUS_HANDLE |
SetServiceStatus | 向 SCM 報告狀態變化 | SERVICE_STATUS 結構 (dwCurrentState, dwControlsAccepted, dwCheckPoint, dwWaitHint) |
ControlService | 發送控制碼 (停止/暫停/…) | SERVICE_CONTROL_STOP 等 |
// Service.cpp
#include
#include
SERVICE_STATUS_HANDLE g_hStatus = NULL;
SERVICE_STATUS g_Status = {0};
HANDLE g_hStopEvent = NULL;
HANDLE g_hWorkerThread = NULL;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI CtrlHandler(DWORD ctrlCode);
DWORD WINAPI WorkerThread(LPVOID lpParam);
VOID ReportStatus(DWORD state, DWORD exitCode, DWORD waitHint);
int _tmain() {
SERVICE_TABLE_ENTRY dispatchTable[] = {
{ _T("MyCppBuilderService"), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
StartServiceCtrlDispatcher(dispatchTable); // 進入 SCM 循環,不返回
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv) {
g_hStatus = RegisterServiceCtrlHandler(_T("MyCppBuilderService"), CtrlHandler);
g_Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ReportStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
g_hWorkerThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, NULL);
ReportStatus(SERVICE_RUNNING, NO_ERROR, 0);
// ServiceMain 返回即視為服務停止,這裡阻塞等待工作線程結束
WaitForSingleObject(g_hWorkerThread, INFINITE);
CloseHandle(g_hStopEvent);
CloseHandle(g_hWorkerThread);
ReportStatus(SERVICE_STOPPED, NO_ERROR, 0);
}
VOID WINAPI CtrlHandler(DWORD ctrlCode) {
switch (ctrlCode) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 3000);
SetEvent(g_hStopEvent); // 通知工作線程退出
break;
case SERVICE_CONTROL_PAUSE: /* 暫停邏輯 */ break;
case SERVICE_CONTROL_CONTINUE: /* 繼續邏輯 */ break;
case SERVICE_CONTROL_INTERROGATE: break;
}
}
DWORD WINAPI WorkerThread(LPVOID lpParam) {
while (WaitForSingleObject(g_hStopEvent, 1000) == WAIT_TIMEOUT) {
// ===== 在此填寫您的業務邏輯 =====
// 例:定時檢測、數據同步、網絡監聽、文件處理…
}
return 0;
}
VOID ReportStatus(DWORD state, DWORD exitCode, DWORD waitHint) {
g_Status.dwCurrentState = state;
g_Status.dwWin32ExitCode = exitCode;
g_Status.dwWaitHint = waitHint;
if (state == SERVICE_START_PENDING)
g_Status.dwControlsAccepted = 0;
else
g_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(g_hStatus, &g_Status);
}
bool InstallService(LPCTSTR exePath, LPCTSTR svcName, LPCTSTR displayName) {
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM) return false;
SC_HANDLE hSvc = CreateService(hSCM, svcName, displayName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
exePath, NULL, NULL, NULL, NULL, NULL);
bool ok = (hSvc != NULL);
if (hSvc) CloseServiceHandle(hSvc);
CloseServiceHandle(hSCM);
return ok;
}
bool UninstallService(LPCTSTR svcName) {
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM) return false;
SC_HANDLE hSvc = OpenService(hSCM, svcName, DELETE);
bool ok = false;
if (hSvc) {
ok = DeleteService(hSvc);
CloseServiceHandle(hSvc);
}
CloseServiceHandle(hSCM);
return ok;
}
Advapi32.lib (SCM API 所在);Run → Parameters → Host Application = services.exe 或裝上後用 Attach to Process;掌握 SCM API 流程與狀態機,即可在 C++Builder 中編寫穩健、可管理的 Windows 服務程序,實現真正的無人值守後台服務。