首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 程序安裝包中自動註冊 Windows 服務實現

     編輯:程式設計綜合問答

核心 API 序列

OpenSCManager → CreateService → ChangeServiceConfig2 (描述) → StartService → CloseHandle

完整代碼(安裝時調用)

#include <windows.h>
#include <tchar.h>

BOOL InstallAndStartService(LPCTSTR szServiceName, LPCTSTR szDisplayName, LPCTSTR szDescription) {
    SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hSCM) return FALSE;

    TCHAR szPath[MAX_PATH];
    GetModuleFileName(NULL, szPath, MAX_PATH); // 當前 exe 路徑

    SC_HANDLE hService = CreateService(
        hSCM,
        szServiceName,           // 服務名
        szDisplayName,           // 顯示名
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_AUTO_START,      // 自動啟動
        SERVICE_ERROR_NORMAL,
        szPath,                  // 執行文件路徑
        NULL, NULL, L"", NULL, NULL
    );

    if (!hService) {
        DWORD err = GetLastError();
        if (err == ERROR_SERVICE_EXISTS) {
            hService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS);
        } else {
            CloseServiceHandle(hSCM);
            return FALSE;
        }
    }

    // 設置描述
    SERVICE_DESCRIPTION desc = {0};
    desc.lpDescription = (LPTSTR)szDescription;
    ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc);

    // 啟動服務
    StartService(hService, 0, NULL);

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCM);
    return TRUE;
}

服務主程序入口要求

// 必須實現 ServiceMain 和 Handler
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) {
    g_StatusHandle = RegisterServiceCtrlHandler(szServiceName, ServiceCtrlHandler);
    SetServiceStatus(g_StatusHandle, &(SERVICE_STATUS){SERVICE_START_PENDING});
    
    // 初始化...
    SetServiceStatus(g_StatusHandle, &(SERVICE_STATUS){SERVICE_RUNNING});
    
    // 工作循環
    while (g_Running) { Sleep(1000); }
    
    SetServiceStatus(g_StatusHandle, &(SERVICE_STATUS){SERVICE_STOPPED});
}

void WINAPI ServiceCtrlHandler(DWORD ctrl) {
    if (ctrl == SERVICE_CONTROL_STOP) {
        g_Running = FALSE;
        SetServiceStatus(g_StatusHandle, &(SERVICE_STATUS){SERVICE_STOP_PENDING});
    }
}

int _tmain(int argc, TCHAR* argv[]) {
    if (argc > 1 && _tcscmp(argv[1], _T("/install")) == 0) {
        InstallAndStartService(...);
        return 0;
    }
    if (argc > 1 && _tcscmp(argv[1], _T("/uninstall")) == 0) { /* DeleteService */ return 0; }
    
    // 以服務運行
    SERVICE_TABLE_ENTRY dispatch[] = {{szServiceName, ServiceMain}, {NULL, NULL}};
    StartServiceCtrlDispatcher(dispatch);
    return 0;
}

打包工具推薦

工具特點
Inno Setup腳本靈活、支持 [Run] 節執行 my.exe /install、體積小
NSIS功能強大、邏輯複雜、學習曲線陡
WiX Toolset微軟官方、生成 MSI、企業級首選、XML 配置繁瑣

Inno Setup 關鍵腳本片段

[Run]
Filename: "{app}\MyService.exe"; Parameters: "/install"; Description: "安裝並啟動服務"; Flags: runhidden waituntilterminated

[UninstallRun]
Filename: "{app}\MyService.exe"; Parameters: "/uninstall"; Flags: runhidden waituntilterminated

Windows 服務安裝**必須管理員權限**。安裝包請在清單文件或 Inno Setup 中聲明 RequireAdministrator,否則 CreateService 返回 ERROR_ACCESS_DENIED (5)。

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