首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 建立 Windows 服務應用程序完整教程

     編輯:VC 教學

為什麼選擇服務程序?

Windows 服務(Service)具有獨特優勢:

  • 自動啟動:系統啟動即運行,無需用戶登錄
  • 後台運行:無用戶界面,不佔用桌面資源
  • 高權限:以 SYSTEM 或指定賬戶運行,訪問系統資源
  • 生命週期管理:SCM(服務控制管理器)統一管理啟動/停止/暫停

適合:監控程序、數據同步、網絡服務、定時任務等長期運行場景。

核心 API 概覽

實現步驟詳解

1. 項目創建與全局定義

  • 創建 Win32 Application(無界面),命名 ServiceTest
  • 定義全局變量:服務名、狀態結構、狀態句柄、線程 ID
  • 聲明核心函數:Init、Install、Uninstall、ServiceMain、ServiceCtrl

2. 初始化函數 Init()

hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP; // 關鍵:接受停止控制
status.dwWin32ExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;

3. 安裝服務 Install()

SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hService = CreateService(
    hSCM, szServiceName, szServiceName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
    SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
    szFilePath, NULL, NULL, L"", NULL, NULL);
// 關鍵參數:SERVICE_DEMAND_START = 手動啟動
// 若需自動啟動改為 SERVICE_AUTO_START
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);

4. 卸載服務 Uninstall()

SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hService = OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
ControlService(hService, SERVICE_CONTROL_STOP, &status); // 先停止
DeleteService(hService); // 再刪除
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);

5. 服務主線程 ServiceMain()

status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceCtrl);
if (!hServiceStatus) { LogEvent(L"Handler not installed"); return; }

SetServiceStatus(hServiceStatus, &status);
// 初始化完成,進入運行狀態
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &status);

// === 核心業務邏輯放這裡 ===
int i = 0;
while (i < 10) { Sleep(1000); i++; } // 模擬工作 10 秒
// ==========================

status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
LogEvent(L"Service stopped");

6. 控制處理函數 ServiceCtrl()

void WINAPI ServiceCtrl(DWORD dwOpcode) {
    switch (dwOpcode) {
        case SERVICE_CONTROL_STOP:
            status.dwCurrentState = SERVICE_STOP_PENDING;
            SetServiceStatus(hServiceStatus, &status);
            // 執行清理工作...
            status.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hServiceStatus, &status);
            break;
        case SERVICE_CONTROL_PAUSE: /* ... */ break;
        case SERVICE_CONTROL_CONTINUE: /* ... */ break;
        case SERVICE_CONTROL_INTERROGATE: /* ... */ break;
    }
}

7. 入口點 WinMain 命令行分發

Init();
SERVICE_TABLE_ENTRY st[] = {
    { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
    { NULL, NULL }
};

if (stricmp(lpCmdLine, "/install") == 0) Install();
else if (stricmp(lpCmdLine, "/uninstall") == 0) Uninstall();
else {
    if (!StartServiceCtrlDispatcher(st))
        LogEvent(L"Register Service Main Function Error!");
}

用法:

  • ServiceTest.exe /install 安裝服務
  • ServiceTest.exe /uninstall 卸載服務
  • ServiceTest.exe (由 SCM 啟動)運行服務

關鍵注意事項

  1. dwControlsAccepted 必須設置:否則 SCM 不會發送控制碼,服務無法被停止/暫停
  2. 狀態報告及時:每次狀態變化必須調用 SetServiceStatus
  3. 服務類型選擇:SERVICE_WIN32_OWN_PROCESS 獨立進程;SERVICE_WIN32_SHARE_PROCESS 共享進程
  4. 錯誤處理:所有 API 返回值必須檢查,失敗時記錄日誌
  5. 調試技巧:開發階段可作為控制台程序運行,通過條件編譯切換

總結

Windows 服務開發核心在於:理解 SCM 架構、正確實現狀態機、註冊控制處理器、業務邏輯與服務框架分離。掌握本文框架,即可快速構建穩健的後台服務程序。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
API用途
OpenSCManager打開服務控制管理器數據庫
CreateService創建新服務
OpenService打開現有服務獲取句柄
ControlService發送控制碼(停止、暫停等)
DeleteService刪除服務
RegisterServiceCtrlHandler註冊服務控制處理函數
SetServiceStatus報告服務狀態給 SCM
StartServiceCtrlDispatcher連接服務主線程與 SCM