调用ExecMethod时遇WBEM_E_INITIALIZATION_FAILURE错误的求助
WMI创建卷影副本时出现WBEM_E_INITIALIZATION_FAILURE错误排查
问题描述
通过命令行执行wmic shadowcopy call create Volume='c:\'可成功创建C盘卷影副本,但通过C++代码调用ExecMethod时返回错误:ExecMethod failed: WBEM_E_INITIALIZATION_FAILURE(80041014)。已尝试启动Volume Shadow Copy服务但无效果,使用CreateProcess执行相同命令也报初始化失败。
CreateProcess执行报错信息
Executing (Win32_ShadowCopy)->create() ERROR: Description = 初始化失败
相关C++代码
#include <iostream> #include <comdef.h> #include <Wbemidl.h> #include <windows.h> #pragma comment(lib, "wbemuuid.lib") void Cleanup(IWbemServices* pSvc, IWbemLocator* pLoc) { if (pSvc) { pSvc->Release(); } if (pLoc) { pLoc->Release(); } CoUninitialize(); } HRESULT CreateShadowCopy(IWbemServices* pSvc, BSTR* pShadowID) { HRESULT hres; IWbemClassObject* pClass = nullptr; IWbemClassObject* pInParamsDefinition = nullptr; IWbemClassObject* pOutParams = nullptr; IWbemClassObject* pClassInstance = nullptr; // 获取Win32_ShadowCopy类对象 hres = pSvc->GetObject(L"Win32_ShadowCopy", 0, nullptr, &pClass, nullptr); if (FAILED(hres)) { std::wcerr << L"GetObject failed: " << std::hex << hres << std::endl; return hres; } // 获取方法的输入参数定义 hres = pClass->GetMethod(L"Create", 0, &pInParamsDefinition, nullptr); if (FAILED(hres)) { std::wcerr << L"GetMethod failed: " << std::hex << hres << std::endl; pClass->Release(); return hres; } // 创建输入参数实例 hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance); if (FAILED(hres)) { std::wcerr << L"SpawnInstance failed: " << std::hex << hres << std::endl; pInParamsDefinition->Release(); pClass->Release(); return hres; } // 设置输入参数Volume VARIANT vtVolume; VariantInit(&vtVolume); vtVolume.vt = VT_BSTR; vtVolume.bstrVal = SysAllocString(L"C:\\"); hres = pClassInstance->Put(L"Volume", 0, &vtVolume, 0); VariantClear(&vtVolume); if (FAILED(hres)) { std::wcerr << L"Put failed: " << std::hex << hres << std::endl; pClassInstance->Release(); pInParamsDefinition->Release(); pClass->Release(); return hres; } // 执行Create方法 hres = pSvc->ExecMethod(L"Win32_ShadowCopy", L"Create", 0, nullptr, pClassInstance, &pOutParams, nullptr); if (FAILED(hres)) { std::wcerr << L"ExecMethod failed: " << std::hex << hres << std::endl; pClassInstance->Release(); pInParamsDefinition->Release(); pClass->Release(); return hres; } // 获取输出参数ShadowID VARIANT vtShadowID; hres = pOutParams->Get(L"ShadowID", 0, &vtShadowID, nullptr, nullptr); if (FAILED(hres)) { std::wcerr << L"Get ShadowID failed: " << std::hex << hres << std::endl; pOutParams->Release(); pClassInstance->Release(); pInParamsDefinition->Release(); pClass->Release(); return hres; } *pShadowID = SysAllocString(vtShadowID.bstrVal); VariantClear(&vtShadowID); pOutParams->Release(); pClassInstance->Release(); pInParamsDefinition->Release(); pClass->Release(); return S_OK; } int wmain() { HRESULT hres; IWbemLocator* pLoc = nullptr; IWbemServices* pSvc = nullptr; BSTR shadowID = nullptr; // 初始化COM环境 hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { std::wcerr << L"CoInitializeEx failed: " << std::hex << hres << std::endl; return 1; } // 设置COM安全级别 hres = CoInitializeSecurity( nullptr, -1, // COM身份验证 nullptr, // 身份验证服务 nullptr, // 保留参数 RPC_C_AUTHN_LEVEL_DEFAULT, // 默认身份验证级别 RPC_C_IMP_LEVEL_IMPERSONATE,// 默认模拟级别 nullptr, // 身份验证信息 EOAC_NONE, // 额外功能 nullptr // 保留参数 ); if (FAILED(hres)) { std::wcerr << L"CoInitializeSecurity failed: " << std::hex << hres << std::endl; CoUninitialize(); return 1; } // 创建WMI定位器实例 hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); if (FAILED(hres)) { std::wcerr << L"CoCreateInstance failed: " << std::hex << hres << std::endl; CoUninitialize(); return 1; } // 连接到WMI命名空间 hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), nullptr, nullptr, 0, NULL, 0, 0, &pSvc); if (FAILED(hres)) { std::wcerr << L"ConnectServer failed: " << std::hex << hres << std::endl; pLoc->Release(); CoUninitialize(); return 1; } // 设置代理安全 blanket hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); if (FAILED(hres)) { std::wcerr << L"CoSetProxyBlanket failed: " << std::hex << hres << std::endl; Cleanup(pSvc, pLoc); return 1; } // 创建卷影副本 hres = CreateShadowCopy(pSvc, &shadowID); if (FAILED(hres)) { std::wcerr << L"CreateShadowCopy failed: " << std::hex << hres << std::endl; Cleanup(pSvc, pLoc); return 1; } // 输出卷影副本ID std::wcout << L"Shadow Copy ID: " << shadowID << std::endl; // 资源清理 Cleanup(pSvc, pLoc); return 0; }
问题排查及解决方案
权限缺失:创建卷影副本需要管理员权限,命令行通常默认以管理员身份启动,但C++程序和CreateProcess启动的进程可能未获取权限。需确保程序以管理员身份运行:
- 右键程序选择“以管理员身份运行”
- 在项目属性中添加UAC清单,将
requestedExecutionLevel设置为requireAdministrator
WMI权限配置问题:调整WMI连接的安全参数:
- 将
CoSetProxyBlanket中的RPC_C_IMP_LEVEL_IMPERSONATE改为RPC_C_IMP_LEVEL_DELEGATE - 连接WMI时显式传入当前用户凭据,而非使用
nullptr
- 将
依赖服务未启动:确认以下服务处于运行状态:
- Volume Shadow Copy (VSS)
- Microsoft Software Shadow Copy Provider (SWPRV)
- Cryptographic Services (CryptSvc)
参数格式验证:尝试修改Volume参数格式为
L"\\\\?\\C:\\",避免路径解析问题
内容的提问来源于stack exchange,提问作者K.Aguilar
相关产品推荐
相关产品推荐

