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

Windows 服務編程實戰:開機自動關機服務開發與部署完整指南

     編輯:關於C語言

項目背景

本文實現一個安裝為 Windows 服務、開機自動執行關機的「惡搞程序」,旨在演示 Windows 服務編程核心流程:服務安裝、啟動、控制處理、關機權限提升、服務註冊與刪除。僅供技術學習,請勿用於惡意用途。

核心代碼架構解析

1. 服務入口與主循環

SERVICE_TABLE_ENTRY st[] = {
    {TEXT("ShutdownService"), ServiceMain},
    {NULL, NULL}
};
StartServiceCtrlDispatcher(st);

ServiceMain 註冊控制處理函數 HandlerEx,設置服務狀態為 SERVICE_RUNNING,並調用核心邏輯 DoShutdown()。

2. 關機核心邏輯:權限提升與調用

BOOL DoShutdown() {
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    // 1. 獲取進程令牌
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    // 2. 查找 SE_SHUTDOWN_NAME 特權 LUID
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    // 3. 啟用關機特權
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, NULL);
    // 4. 執行關機
    return ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, SHTDN_REASON_MAJOR_OTHER);
}

關鍵點:服務運行於 SYSTEM 權限,但默認未啟用 SE_SHUTDOWN_PRIVILEGE,必須通過 AdjustTokenPrivileges 顯式啟用,否則 ExitWindowsEx 會失敗返回 ERROR_PRIVILEGE_NOT_HELD。

3. 服務控制處理器

VOID WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) {
    switch (dwControl) {
        case SERVICE_CONTROL_STOP:
            g_Status.dwCurrentState = SERVICE_STOP_PENDING;
            SetServiceStatus(g_hStatus, &g_Status);
            // 執行清理工作
            break;
        case SERVICE_CONTROL_SHUTDOWN:
            // 系統關機通知
            break;
    }
}

4. 服務安裝與刪除(命令行參數控制)

// 安裝:創建服務,設置為 SERVICE_AUTO_START(開機自啟)
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE schService = CreateService(schSCManager, "ShutdownService", "Auto Shutdown",
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
    szFilePath, NULL, NULL, NULL, NULL, NULL);

// 刪除:sc delete ShutdownService
SC_HANDLE schService = OpenService(schSCManager, "ShutdownService", DELETE);
DeleteService(schService);

編譯與部署步驟

  1. 使用 Visual Studio 創建「Win32 Console Application」項目,勾選「Empty Project」。
  2. 將代碼放入 main.c,鏈接 Advapi32.lib。
  3. 編譯生成 ShutdownService.exe。
  4. 以管理員身份運行 CMD:
    ShutdownService.exe install (安裝服務)
    ShutdownService.exe start (啟動服務,驗證關機邏輯)
  5. 重啟電腦驗證開機自動關機效果。

卸載與緊急恢復

若需移除該服務,可採取以下任一方式:

  1. 正常卸載:管理員 CMD 執行 sc delete ShutdownService。
  2. 安全模式卸載:開機按 F8 進入安全模式(服務不自動啟動),再執行 sc delete ShutdownService 或手動刪除註冊表 HKLM\SYSTEM\CurrentControlSet\Services\ShutdownService。
  3. 刪除可執行文件:刪除 C:\Windows\System32\ShutdownService.exe(或自定義路徑)。

技術總結與擴展

  • 掌握 ServiceMain、HandlerEx、SetServiceStatus 服務核心三元組。
  • 理解 Windows 權限模型:OpenProcessToken → LookupPrivilegeValue → AdjustTokenPrivileges 標準流程。
  • 服務調試技巧:使用 DebugBreak() + 調試器附加,或寫日誌文件追蹤。
  • 擴展方向:定時任務服務、網絡監聽服務、硬體監控服務、自更新服務。

下載鏈接

完整項目源碼:百度網盤(提取碼見原文)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved