C++通过WMI启动/停止服务,修改服务类型 (

stdafx.h

#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <tchar.h>
#include <string>
using namespace std;

WMI.h
std::string GetServerProperty(LPCWSTR proName, IWbemClassObject *pclsObj);
int GetWin32Info(string wql, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator);
//调用没有参数的方法
int ExecMethod(OLECHAR* sClassName, OLECHAR* sMethodName, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator, IWbemClassObject *&pclsObj);
//调用有参数的方法
int ExecMethod(OLECHAR* sClassName, OLECHAR* sMethodName, LPCWSTR sParaName, OLECHAR* sParaValue, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator, IWbemClassObject *&pclsObj);
WMI.cpp
#include "stdafx.h"
#include "get_hostname_IP_MAC.h"
#include "get_service_info.h"
#include "replace_special_str.h"
#include 

string GetServerProperty(LPCWSTR proName, IWbemClassObject *pclsObj)
{
    char  buf[2000];
    VARIANT vtProp;
    HRESULT hr pclsObj->Get(proName, 0, &vtProp, 0, 0);
    if( hr == WBEM_S_NO_ERROR && vtProp.vt != VT_NULL )
    {
        _bstr_t bstr &vtProp;  //Just to convert BSTR to ANSI
        char* str=(char*)bstr;
        sprintf(buf,"%s", str);
        VariantClear(&vtProp);
        return replace_c(buf);
    }
    return "";
}


int GetWin32Info(string wql, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator)
{
    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------
    HRESULT hres  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. Error code 0x" << hex << hres << endl;
        return 1;                  // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for user by using
    // SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------

    hres  CoInitializeSecurity(
        NULL, 
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );


    if (FAILED(hres))
    {
        cout << "Failed to initialize security. Error code 0x" << hex << hres << endl;
        CoUninitialize();
        return 1;                    // Program has failed.
    }

    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    hres CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);

    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object." << Err code 0x" << hex << hres << endl;
        CoUninitialize();
        return 1;                 // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL current user
        NULL,                    // User password. NULL current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (e.g. Kerberos)
        0,                       // Context object 
        &pSvc                    // pointer to IWbemServices proxy
        );

    if (FAILED(hres))
    {
        cout << "Could not connect. Error code 0x" << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return 1;                // Program has failed.
    }

    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
        );

    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code 0x" << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----
    hres pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t(wql.c_str()),
        WBEM_FLAG_FORWARD_ONLY WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        cout << "Query for operating system name failed." << Error code 0x" << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }

    return 0;
}


int ExecMethod(OLECHAR* sClassName, OLECHAR* sMethodName, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator, IWbemClassObject *&pclsObj)
{
    int iResult 0;

    HRESULT hres;
    ULONG uReturn 0;
    
    
    BSTR MethodName SysAllocString(sMethodName);
    BSTR ClassName SysAllocString(sClassName);
    IWbemClassObject* pClass NULL;
    hres pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
    if (FAILED(hres))
    {
        cout << "pSvc->GetObject failed" << hex << hres << endl;
        return 1;
    }

    //IWbemClassObject* pInParamsDefinition NULL;
    hres pClass->GetMethod(MethodName, 0, NULL, NULL);
    
    if (FAILED(hres))
    {
        cout << "pClass->GetMethod failed" << hex << hres << endl;
        return 1;
    }

    while (pEnumerator)
    {
        HRESULT hr pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if(0 == uReturn)
        {
            break;
        }
        // Get the context for non-static method
        CIMTYPE pType;
        LONG pFlavor;
        VARIANT var;
        pclsObj->Get(L"__PATH", 0, &var, &pType, &pFlavor);

        // Execute Method
        IWbemClassObject *pOutParams NULL;
        hres pSvc->ExecMethod(var.bstrVal, MethodName, 0, NULL, NULL, &pOutParams, NULL);

        if(FAILED(hres))
        {
            //失败
            cout << "Could not execute method. Error code 0x" << hex << hres << endl;
            iResult 1;
        }
        else
        {
            //成功
            VARIANT varReturnValue;
            hres pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
            if (varReturnValue.lVal == 0)
            {
                //cout << varReturnValue.lVal << endl;
                cout << "execute method << MethodName << success." << endl;
                iResult 0;
            }
            else
            {
                iResult 1;
            }
        }
        pOutParams->Release();
    }

    SysFreeString(ClassName);
    SysFreeString(MethodName);
    pClass->Release();

    return iResult;
}


int ExecMethod(OLECHAR* sClassName, OLECHAR* sMethodName, LPCWSTR sParaName, OLECHAR* sParaValue, IWbemLocator *&pLoc, IWbemServices *&pSvc, IEnumWbemClassObject *&pEnumerator, IWbemClassObject *&pclsObj)
{
    int iResult 0;

    HRESULT hres;
    ULONG uReturn 0;
    
    
    BSTR MethodName SysAllocString(sMethodName);
    BSTR ClassName SysAllocString(sClassName);
    IWbemClassObject* pClass NULL;
    hres pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
    if (FAILED(hres))
    {
        cout << "pSvc->GetObject failed" << hex << hres << endl;
        return 1;
    }

    IWbemClassObject* pInParamsDefinition NULL;
    hres pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL);
    
    if (FAILED(hres))
    {
        cout << "pClass->GetMethod failed" << hex << hres << endl;
        return 1;
    }

    IWbemClassObject* pClassInstance NULL;
    hres pInParamsDefinition->SpawnInstance(0, &pClassInstance);
    VARIANT varCommand;
    varCommand.vt VT_BSTR;
    varCommand.bstrVal SysAllocString(sParaValue);

    // Store the value for the in parameters
    hres pClassInstance->Put(sParaName, 0, &varCommand, 0);
    wprintf(L"The command is: %s\n", V_BSTR(&varCommand));

    while (pEnumerator)
    {
        HRESULT hr pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if(0 == uReturn)
        {
            break;
        }
        // Get the context for non-static method
        CIMTYPE pType;
        LONG pFlavor;
        VARIANT var;
        pclsObj->Get(L"__PATH", 0, &var, &pType, &pFlavor);

        // Execute Method
        IWbemClassObject* pOutParams NULL;
        hres pSvc->ExecMethod(var.bstrVal, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);

        if(FAILED(hres))
        {
            cout << "Could not execute method. Error code 0x" << hex << hres << endl;
            iResult 1;
        }
        else
        {
            VARIANT varReturnValue;
            hres pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
            if (varReturnValue.lVal == 0)
            {
                //cout << varReturnValue.lVal << endl;
                cout << "execute method << MethodName << success." << endl;
                iResult 0;
            }
            else
            {
                iResult 1;
            }
        }

        pOutParams->Release();
    }

    VariantClear(&varCommand);
    SysFreeString(ClassName);
    SysFreeString(MethodName);
    pInParamsDefinition->Release();
    pClass->Release();

    return iResult;
}
Service_ctrl.h

#pragma once

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include "WMI.h"
# pragma comment(lib, "wbemuuid.lib")
using namespace std;

#define _WIN32_DCOM

bool ServiceCtrl(const char* ServiceName, DWORD cmd);
bool MyStartService(SC_HANDLE schSCManager, LPSTR lpServiceName);

Service_ctrl.cpp
#include "stdafx.h"
#include "Service_ctrl.h"


bool IsSuccess(const char* ServiceName, DWORD cmd)
{
    bool bResult false;
    IWbemLocator *pLoc NULL;
    IWbemServices *pSvc NULL;
    IEnumWbemClassObject *pEnumerator NULL;
    IWbemClassObject *pclsObj;

    string sWql "SELECT FROM Win32_Service where Name='";
    sWql += ServiceName;
    sWql += "'";
    int iResult GetWin32Info(sWql, pLoc, pSvc, pEnumerator);
    if (iResult == 1)
    {
        //初始化失败
        return false;
    }
    ULONG uReturn 0;
    while (pEnumerator)
    {
        HRESULT hr pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if(0 == uReturn)
        {
            break;
        }

        string sState GetServerProperty(L"State", pclsObj);
        string sStartMode GetServerProperty(L"StartMode", pclsObj);
        switch(cmd)
        {
            case 1://启动服务
                if (sState.find("Running") != string::npos)
                    bResult true;
                break;
            case 0://停止服务
                if (sState.find("Stopped") != string::npos)
                    bResult true;
                break;
            case 2://设置服务启动状态为“手动”
                if (sStartMode.find("Manual") != string::npos)
                    bResult true;
                break;
            case 3://设置服务启动状态为“自动”
                if (sStartMode.find("Auto") != string::npos)
                    bResult true;
                break;
            case 4://设置服务启动状态为“禁用”
                if (sStartMode.find("Disabled") != string::npos)
                    bResult true;
                break;
        }
    }

    pEnumerator->Release();
    pLoc->Release();
    pSvc->Release();
    CoUninitialize();

    return bResult;
}


bool ServiceCtrl(const char* ServiceName, DWORD cmd)
{
    bool bResult true;
    IWbemLocator *pLoc NULL;
    IWbemServices *pSvc NULL;
    IEnumWbemClassObject *pEnumerator NULL;
    IWbemClassObject *pclsObj;

    string sWql "SELECT FROM Win32_Service where Name='";
    sWql += ServiceName;
    sWql += "'";
    int iResult GetWin32Info(sWql, pLoc, pSvc, pEnumerator);
    if (iResult == 1)
    {
        //初始化失败
        return false;
    }

    OLECHAR *paraValue;
    LPCWSTR ParaName;
    OLECHAR *methodName;

    switch(cmd)
    {
        case 1://启动服务
            methodName L"StartService";
            break;
        case 0://停止服务
            methodName L"StopService";
            break;
        case 2://设置服务启动状态为“手动”
            methodName L"ChangeStartMode";
            ParaName L"StartMode";
            paraValue L"Manual";
            break;
        case 3://设置服务启动状态为“自动”
            methodName L"ChangeStartMode";
            ParaName L"StartMode";
            paraValue L"Automatic";
            break;
        case 4://设置服务启动状态为“禁用”
            methodName L"ChangeStartMode";
            ParaName L"StartMode";
            paraValue L"Disabled";
            break;
    }

    //iResult ExecMethod(L"Win32_Service", L"ChangeStartMode", L"StartMode", L"Disabled", pLoc, pSvc, pEnumerator, pclsObj);

    switch(cmd)
    {
        case 0://停止服务
        case 1://启动服务
            iResult ExecMethod(L"Win32_Service", methodName, pLoc, pSvc, pEnumerator, pclsObj);
            break;
        case 2://设置服务启动状态为“手动”
        case 3://设置服务启动状态为“自动”
        case 4://设置服务启动状态为“禁用”
            iResult ExecMethod(L"Win32_Service", methodName, ParaName, paraValue, pLoc, pSvc, pEnumerator, pclsObj);
            break;
    }
    if (iResult == 1)
    {
        //执行方法失败
        bResult false;
    }
    
    pEnumerator->Release();
    pLoc->Release();
    pSvc->Release();
    CoUninitialize();

    if (bResult)
    {
        //如果一个服务启动很慢,不知道怎样才能知道服务是否启动/停止成功,所以做10次循环,如果10之后,还没有成功,就表示启动/停止失败
        //10次循环共100秒,即1分钟40秒
        for (int 0; 10; i++)
        {
            bResult IsSuccess(ServiceName, cmd);
            if (bResult)
                break;
            else
                Sleep(10000);//休眠10秒
        }
    }

    return bResult;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值