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 配置繁瑣 |
[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)。