1. 程式人生 > >C/C++ Windows API——關閉、啟動、查詢服務狀態

C/C++ Windows API——關閉、啟動、查詢服務狀態

// ServiceDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>

int main()
{
    BOOL ret;
    /*
    _Must_inspect_result_ WINADVAPI SC_HANDLE WINAPI OpenSCManagerW(
        _In_opt_        LPCWSTR                lpMachineName,
        _In_opt_        LPCWSTR                lpDatabaseName,
        _In_            DWORD                  dwDesiredAccess
    );

    dwDesiredAccess可以是如下值
    #define SC_MANAGER_CONNECT             0x0001
#define SC_MANAGER_CREATE_SERVICE 0x0002 #define SC_MANAGER_ENUMERATE_SERVICE 0x0004 #define SC_MANAGER_LOCK 0x0008 #define SC_MANAGER_QUERY_LOCK_STATUS 0x0010 #define SC_MANAGER_MODIFY_BOOT_CONFIG 0x0020 #define SC_MANAGER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \
SC_MANAGER_CONNECT | \ SC_MANAGER_CREATE_SERVICE | \ SC_MANAGER_ENUMERATE_SERVICE | \ SC_MANAGER_LOCK | \
SC_MANAGER_QUERY_LOCK_STATUS | \ SC_MANAGER_MODIFY_BOOT_CONFIG) */ LPCWSTR lpMachineName = NULL; LPCWSTR lpDatabaseName = NULL; DWORD dwSCManagerDesiredAccess = SC_MANAGER_ALL_ACCESS; SC_HANDLE scHandle = OpenSCManager(lpMachineName, lpDatabaseName, dwSCManagerDesiredAccess); if (scHandle == NULL) { printf("OpenSCManager -> ret=0 -> fail(%ld)\n", GetLastError()); } else { printf("OpenSCManager -> succ\n"); /* _Must_inspect_result_ WINADVAPI SC_HANDLE WINAPI OpenService( _In_ SC_HANDLE hSCManager, _In_ LPCTSTR lpServiceName, _In_ DWORD dwDesiredAccess ); #define SERVICE_QUERY_CONFIG 0x0001 #define SERVICE_CHANGE_CONFIG 0x0002 #define SERVICE_QUERY_STATUS 0x0004 #define SERVICE_ENUMERATE_DEPENDENTS 0x0008 #define SERVICE_START 0x0010 #define SERVICE_STOP 0x0020 #define SERVICE_PAUSE_CONTINUE 0x0040 #define SERVICE_INTERROGATE 0x0080 #define SERVICE_USER_DEFINED_CONTROL 0x0100 #define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ SERVICE_QUERY_CONFIG | \ SERVICE_CHANGE_CONFIG | \ SERVICE_QUERY_STATUS | \ SERVICE_ENUMERATE_DEPENDENTS | \ SERVICE_START | \ SERVICE_STOP | \ SERVICE_PAUSE_CONTINUE | \ SERVICE_INTERROGATE | \ SERVICE_USER_DEFINED_CONTROL) */ //列印服務 LPCTSTR lpServiceName = _T("Spooler"); DWORD dwDesiredAccess = SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP; SC_HANDLE serviceHandle = OpenService(scHandle, lpServiceName, dwDesiredAccess); if (serviceHandle == NULL) { printf("OpenService scHandle=%p, lpServiceName=%s -> ret=0 -> fail(%ld)\n", scHandle, lpServiceName, GetLastError()); } else { printf("OpenService scHandle=%p, lpServiceName=%s -> serviceHandle=%p\n", scHandle, lpServiceName, serviceHandle); /* WINADVAPI BOOL WINAPI StartServiceW( _In_ SC_HANDLE hService, _In_ DWORD dwNumServiceArgs, _In_reads_opt_(dwNumServiceArgs) LPCWSTR *lpServiceArgVectors ); */ ret = StartService(serviceHandle, NULL, NULL); if (!ret) { //〖1056〗-服務的例項已在執行中。 printf("StartService serviceHandle=%p -> fail(%ld)\n", serviceHandle, GetLastError()); } else { printf("StartService serviceHandle=%p -> succ\n", serviceHandle); /* _Must_inspect_result_ WINADVAPI BOOL WINAPI QueryServiceStatus( _In_ SC_HANDLE hService, _Out_ LPSERVICE_STATUS lpServiceStatus ); typedef struct _SERVICE_STATUS { DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; } SERVICE_STATUS, *LPSERVICE_STATUS; dwServiceType可以是下列值 #define SERVICE_KERNEL_DRIVER 0x00000001 #define SERVICE_FILE_SYSTEM_DRIVER 0x00000002 #define SERVICE_ADAPTER 0x00000004 #define SERVICE_RECOGNIZER_DRIVER 0x00000008 #define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER | \ SERVICE_FILE_SYSTEM_DRIVER | \ SERVICE_RECOGNIZER_DRIVER) #define SERVICE_WIN32_OWN_PROCESS 0x00000010 #define SERVICE_WIN32_SHARE_PROCESS 0x00000020 #define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS | \ SERVICE_WIN32_SHARE_PROCESS) #define SERVICE_INTERACTIVE_PROCESS 0x00000100 #define SERVICE_TYPE_ALL (SERVICE_WIN32 | \ SERVICE_ADAPTER | \ SERVICE_DRIVER | \ SERVICE_INTERACTIVE_PROCESS) dwCurrentState可以是如下值 #define SERVICE_STOPPED 0x00000001 #define SERVICE_START_PENDING 0x00000002 #define SERVICE_STOP_PENDING 0x00000003 #define SERVICE_RUNNING 0x00000004 #define SERVICE_CONTINUE_PENDING 0x00000005 #define SERVICE_PAUSE_PENDING 0x00000006 #define SERVICE_PAUSED 0x00000007 */ SERVICE_STATUS serviceStatus = { 0 }; do { ret = QueryServiceStatus(serviceHandle, &serviceStatus); //休眠(掛起執行緒),單位毫秒 Sleep(300); } while (ret && serviceStatus.dwCurrentState != SERVICE_RUNNING); } /* WINADVAPI BOOL WINAPI ControlService( _In_ SC_HANDLE hService, _In_ DWORD dwControl, //需要有SERVICE_USER_DEFINED_CONTROL許可權。 _Out_ LPSERVICE_STATUS lpServiceStatus ); dwControl可以取如下值 #define SERVICE_CONTROL_STOP 0x00000001 #define SERVICE_CONTROL_PAUSE 0x00000002 #define SERVICE_CONTROL_CONTINUE 0x00000003 #define SERVICE_CONTROL_INTERROGATE 0x00000004 #define SERVICE_CONTROL_SHUTDOWN 0x00000005 #define SERVICE_CONTROL_PARAMCHANGE 0x00000006 #define SERVICE_CONTROL_NETBINDADD 0x00000007 #define SERVICE_CONTROL_NETBINDREMOVE 0x00000008 #define SERVICE_CONTROL_NETBINDENABLE 0x00000009 #define SERVICE_CONTROL_NETBINDDISABLE 0x0000000A #define SERVICE_CONTROL_DEVICEEVENT 0x0000000B #define SERVICE_CONTROL_HARDWAREPROFILECHANGE 0x0000000C #define SERVICE_CONTROL_POWEREVENT 0x0000000D #define SERVICE_CONTROL_SESSIONCHANGE 0x0000000E #define SERVICE_CONTROL_PRESHUTDOWN 0x0000000F #define SERVICE_CONTROL_TIMECHANGE 0x00000010 #define SERVICE_CONTROL_TRIGGEREVENT 0x00000020 */ DWORD dwControl = SERVICE_CONTROL_STOP; SERVICE_STATUS serviceStatus = { 0 }; //關閉服務 ret = ControlService(serviceHandle, dwControl, &serviceStatus); //〖1052〗-請求的控制元件對此服務無效。〖1062〗-服務未啟動。 printf("ControlService serviceHandle=%p, dwControl=%ld -> ret=%d, GetLastError()=%ld -> serviceStatus.dwServiceType=%ld, dwCurrentState=%ld, dwControlsAccepted=%ld, dwWin32ExitCode=%ld, dwServiceSpecificExitCode=%ld, dwCheckPoint=%ld, dwWaitHint=%ld\n", serviceHandle, dwControl, ret, GetLastError(), serviceStatus.dwServiceType, serviceStatus.dwCurrentState, serviceStatus.dwControlsAccepted, serviceStatus.dwWin32ExitCode, serviceStatus.dwServiceSpecificExitCode, serviceStatus.dwCheckPoint, serviceStatus.dwWaitHint ); //The CloseServiceHandle function does not destroy the service control manager object referred to by the handle. A service control manager object cannot be destroyed. A service object can be destroyed by calling the DeleteService function. CloseServiceHandle(serviceHandle); DeleteService(serviceHandle); } CloseServiceHandle(scHandle); DeleteService(serviceHandle); } system("pause"); return 0; }

這裡寫圖片描述

程式碼中用於測試的服務是Spooler(即列印服務)
這裡寫圖片描述