如何解决使用 C++ 中的 WMI 在本地复制文件
我想使用 CIM_DataFile 对象将本地计算机中的文件复制到本地目录(无远程)。
这是我当前的 C++ 代码:
BOOL WmicCopy(char* from,char* to) {
HRESULT hres;
BSTR ClassName = SysAllocString(L"CIM_DataFile");
BSTR MethodName = SysAllocString(L"Copy");
IWbemClassObject* pCIMDataFile = NULL;
IWbemClassObject* pCopyMethodClass = NULL;
IWbemClassObject* pCopyParamsInstance = NULL;
char* query = new char[512];
ZeroMemory(query,512);
strcat(query,"CIM_DataFile.Name=\'");
strcat(query,from);
strcat(query,"\'");
//Get WMI Svc Instance
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,CLSCTX_INPROC_SERVER,IID_IWbemLocator,(LPVOID*)&pLoc);
if (FAILED(hres))
{
debug_printf("Failed to create IWbemLocator object. Error code = 0x%x\n",hres);
CoUninitialize();
return FALSE; // Program has failed.
}
IWbemServices* pSvc = NULL;
// Connect to the local root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),NULL,&pSvc
);
if (FAILED(hres))
{
debug_printf("Could not connect. Error code = 0x%x\n",hres);
pLoc->Release();
CoUninitialize();
return FALSE; // Program has failed.
}
debug_printf("Connected to wmi namespace.\n");
// Set security levels for 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))
{
debug_printf("Could not set proxy blanket. Error code = 0x%x\n",hres);
pSvc->Release();
pLoc->Release();
CoUninitialize();
return FALSE; // Program has failed.
}
//Get CIM DataFile object
debug_printf("Running query: %s\n",query);
hres = pSvc->GetObjectA(_bstr_t(query),&pCIMDataFile,NULL);
if (FAILED(hres)) {
debug_printf("Failed to get object from file path: 0x%x\n",hres);
}
// set up to call the Win32_Process::Create method
// Create the values for the in parameters
VARIANT varTo;
varTo.vt = VT_BSTR;
varTo.bstrVal = _bstr_t(to);
hres = pCIMDataFile->GetMethod(MethodName,&pCopyMethodClass,NULL);
if (FAILED(hres)) {
debug_printf("Failed to get method: 0x%x\n",hres);
}
hres = pCopyMethodClass->SpawnInstance(0,&pCopyParamsInstance);
if (FAILED(hres)) {
debug_printf("Failed to spawn instance: 0x%x\n",hres);
}
// Store the value for the in parameters
hres = pCopyParamsInstance->Put(L"FileName",&varTo,0);
if (FAILED(hres)) {
debug_printf("Failed to set param value: 0x%x\n",hres);
}
debug_printf("File to copy to is: %ls\n",V_BSTR(&varTo));
// Execute Method
IWbemClassObject* pOutParams = NULL;
hres = pSvc->ExecMethod(
_bstr_t(query),//strObjectPath
MethodName,//strMethodName
0,//iFlags
NULL,//IWbemContext *pCt
pCopyParamsInstance,//IWbemClassObject *pInParams
&pOutParams,//IWbemClassObject *pOutParams
NULL); //ppCallResult
if (FAILED(hres))
{
debug_printf("Could not execute method. Error code = 0x%x\n",hres);
VariantClear(&varTo);
SysFreeString(ClassName);
SysFreeString(MethodName);
if (pCopyMethodClass)
pCopyMethodClass->Release();
if (pCopyParamsInstance)
pCopyParamsInstance->Release();
pCIMDataFile->Release();
pOutParams->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return FALSE; // Program has failed.
}
// To see what the method returned,// use the following code. The return value will
// be in &varReturnValue
VARIANT varReturnValue = {};
ZeroMemory(&varReturnValue,sizeof(VARIANT));
hres = pOutParams->Get(_bstr_t(L"ReturnValue"),&varReturnValue,0);
// Clean up
//--------------------------
//VariantClear(&varTo);
//VariantClear(&varReturnValue);
if (pCopyMethodClass)
pCopyMethodClass->Release();
if (pCopyParamsInstance)
pCopyParamsInstance->Release();
SysFreeString(MethodName);
SysFreeString(ClassName);
pCIMDataFile->Release();
pLoc->Release();
pSvc->Release();
return TRUE;
}
这是输出,它在 hres = pCIMDataFile->GetMethod(MethodName,NULL); 处以 WBEM_E_ILLEGAL_OPERATION 失败;
完整输出:
Connected to wmi namespace.
Running query: CIM_DataFile.Name='C:\Windows\System32\cmd.exe'
Failed to get method: 0x8004101e
这是我尝试用 C++ 编写的有效 Visual Basic 代码(将 cmd.exe 复制到桌面上的 bab.exe):
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
' Obtain an instance of the the class
' using a key property value.
Set objShare = objWMIService.Get("CIM_DataFile.Name='C:\\Windows\\System32\\cmd.exe'")
' Obtain an InParameters object specific
' to the method.
Set objInParam = objShare.Methods_("Copy"). _
inParameters.SpawnInstance_()
' Add the input parameters.
objInParam.Properties_.Item("FileName") = "C:\\Users\\User\\Desktop\\baba.exe"
' Execute the method and obtain the return status.
' The OutParameters object in objOutParams
' is created by the provider.
Set objOutParams = objWMIService.ExecMethod("CIM_DataFile.Name='C:\\Windows\\System32\\cmd.exe'","Copy",objInParam)
' List OutParams
Wscript.Echo "Out Parameters: "
Wscript.echo "ReturnValue: " & objOutParams.ReturnValue
为什么类似的 GetMethod 调用在 VB 中有效,而在 C++ 中无效? (原谅 C++ 代码中混乱的错误处理,在正确编写清理跳转之前试图获取一个结构)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。