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

VC++ 啟動與停止 Windows 服務:OpenSCManager/StartService/ControlService 完整範例

     編輯:VC 教學

前言

應用程式常需以程式控制服務啟動/停止(如 IIS 的 W3SVC、資料庫服務)。本文示範使用服務控制管理器 API 完整流程:開啟 SCM、開啟服務、查詢狀態、啟動/停止、等待狀態轉換完成。

核心程式碼


#include 

void StartStopWebService()
{
    // 1. 開啟服務控制管理器
    SC_HANDLE hSCM = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
    if (!hSCM) { TRACE(_T("OpenSCManager 失敗: %d\n"), GetLastError()); return; }

    // 2. 開啟目標服務 (需 START/STOP/QUERY 權限)
    SC_HANDLE hSvc = OpenService(hSCM, _T("W3SVC"),
        SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS);
    if (!hSvc) { TRACE(_T("OpenService 失敗: %d\n"), GetLastError());
        CloseServiceHandle(hSCM); return; }

    // 3. 取得目前狀態
    SERVICE_STATUS status;
    if (!QueryServiceStatus(hSvc, &status)) {
        TRACE(_T("QueryServiceStatus 失敗\n"));
        CloseServiceHandle(hSvc); CloseServiceHandle(hSCM); return;
    }

    // 4. 依狀態決定啟動或停止
    if (status.dwCurrentState == SERVICE_RUNNING) {
        // --- 停止服務 ---
        if (!ControlService(hSvc, SERVICE_CONTROL_STOP, &status)) {
            TRACE(_T("ControlService STOP 失敗\n"));
        } else {
            // 等待真正停止
            while (QueryServiceStatus(hSvc, &status)) {
                if (status.dwCurrentState == SERVICE_STOPPED) {
                    AfxMessageBox(_T("服務已停止"));
                    break;
                }
                Sleep(status.dwWaitHint > 0 ? status.dwWaitHint : 1000);
            }
        }
    }
    else if (status.dwCurrentState == SERVICE_STOPPED) {
        // --- 啟動服務 ---
        if (!StartService(hSvc, 0, NULL)) {
            TRACE(_T("StartService 失敗: %d\n"), GetLastError());
        } else {
            while (QueryServiceStatus(hSvc, &status)) {
                if (status.dwCurrentState == SERVICE_RUNNING) {
                    AfxMessageBox(_T("服務已啟動"));
                    break;
                }
                Sleep(status.dwWaitHint > 0 ? status.dwWaitHint : 1000);
            }
        }
    }

    // 5. 清理
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hSCM);
}

關鍵 API 說明

API用途關鍵參數
OpenSCManager連線服務控制管理器機器名(NULL=本機)、資料庫名(NULL=預設)、存取權限
OpenService取得服務控制代碼SCM 控制代碼、服務名稱、存取權限
QueryServiceStatus取得服務目前狀態服務控制代碼、輸出 SERVICE_STATUS
StartService啟動服務服務控制代碼、引數個數、引數陣列
ControlService發送控制碼服務控制代碼、控制碼(SERVICE_CONTROL_STOP 等)、輸出狀態
CloseServiceHandle關閉控制代碼SCM 或服務控制代碼

權限需求

  • 呼叫進程需**管理員權限**(UAC 提升),否則 OpenService 會傳回 ERROR_ACCESS_DENIED (5)。
  • 服務名稱(如 W3SVC)可用 services.msc 或 sc query 確認。

非同步等待最佳化

單純 Sleep 輪詢會阻塞 UI 執行緒。建議:

  • 在工作執行緒執行上述流程,透過 PostMessage 通知 UI 狀態變化。
  • 或使用 WaitForSingleObject 搭配服務專用事件(需服務支援)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved