调用提供程序方法
提供程序方法是由 Windows Management Instrumentation (WMI) 提供程序实现的方法。 该方法位于提供程序定义的类中,用于表示来自软件或硬件的数据。 例如,Win32_Service 类具有启动、停止、继续、暂停和更改服务的方法。
提供程序方法不应与以下类型的方法混淆:
- WMI 系统类上的方法,例如 __SystemSecurity 上的 GetSD 方法。
- 用于 WMI 的脚本 API 中对象的方法,例如 SWbemServices.InstancesOf。
- 用于 WMI 的 COM API 中的方法,例如 IWbemLocator::ConnectServer。
使用脚本调用提供程序方法
VBScript、PowerShell 或 Perl 等任何自动化语言都可以调用 WMI 方法。 部分语言可以使用直接访问,但其他语言必须使用 SWbemServices.ExecMethod 间接执行提供程序方法。
以下过程介绍如何使用脚本 API 和直接访问调用提供程序方法。
若要使用脚本 API 和直接访问调用提供程序方法
将此方法用于 VBScript 或 PowerShell。
确定是否实现了想执行的方法。
某些类定义了提供程序不支持的方法。 如果未实现方法,则无法执行该方法。 可以通过检查方法是否具有 Implemented 限定符来确定方法是否实现。 有关详细信息,请参阅 WMI 限定符和访问 WMI 限定符。 还可以通过运行不受支持的 Wbemtest.exe 实用工具(该实用工具在安装了 WMI 的任何操作系统上都可用)来确定提供程序类方法是否设置 Implemented 限定符。
确定要执行的方法是静态方法还是非静态方法。
静态方法仅适用于 WMI 类,不适用于类的特定实例。 例如,Win32_Process 类的 Create 方法是静态方法,因为它用于创建没有此类实例的新进程。 非静态方法仅适用于类的实例。 例如,Win32_Process 类的 Terminate 方法是非静态方法,因为只有当进程实例存在时终止进程才有意义。 可以通过检查 Static 限定符是否与方法关联来确定方法是否为静态。
检索包含要执行的方法的类或实例。
有关详细信息,请参阅检索 WMI 类或实例数据。
设置方法可能需要的任何安全设置。
通常可以通过检查方法的 Privileges 限定符中的值来确定方法所需的特权。 例如,Win32_OperatingSystem 类 Shutdown 方法要求设置“SeShutdownPrivilege”特权。 有关详细信息,请参阅执行特权操作。
调用方法并检查返回值以确定方法是否成功。
以下代码示例创建一个记事本进程,并使用直接访问获取进程 ID。
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer _
& "\root\cimv2:Win32_Process")
Error = objWMIService.Create("notepad.exe", null, _
null, intProcessID)
If Error = 0 Then
Wscript.Echo "Notepad was started with a process ID of " _
& intProcessID & "."
Else
Wscript.Echo "Notepad could not be started due to error " _
& Error & "."
End If
try
{
$myProcess = ([wmiclass]"win32_process").create("notepad.exe", $null, $null)
}
catch
{
"Notepad could not be started due to the following error:"
$error[0]
return
}
#else
"Notepad was started with a process ID of " + $myProcess.ProcessID
以下过程介绍如何使用脚本 API 和 SWbemServices.ExecMethod 调用提供程序方法。
若要使用脚本 API 和 SWbemServices.ExecMethod 调用提供程序方法
- 检索 WMI 类定义以执行静态方法。 检索 WMI 类实例以执行非静态方法。
- 使用 SWbemObjectSet.Item 方法从类或实例的 SWbemObject.Methods_ 集合中检索要执行的方法。
- 获取方法的 InParameters 对象,并按照构造 InParameters 对象中所述设置参数。
- 调用 SWbemServices.ExecMethod 方法执行并将返回值分配给 SWbemObject 对象以存储输出参数。
- 检查输出参数对象中的值,验证方法是否正确执行。
以下 VBScript 代码示例通过调用 SWBemServices.ExecMethod 的间接方法执行与上一脚本相同的操作。
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer _
& "\root\cimv2")
Set objProcess = objWMIService.Get("Win32_Process")
' Obtain an InParameters object specific to
' the Win32_Process.Create method.
Set objInParam = _
objProcess.Methods_("Create").inParameters.SpawnInstance_()
' Add the input parameters.
objInParam.Properties_.item("CommandLine") = "Notepad"
objInParam.Properties_.item("CurrentDirectory") = NULL
objInParam.Properties_.item("ProcessStartupInformation") = NULL
Set objOutParams = objProcess.ExecMethod_("Create", objInParam)
If Error = 0 Then
Wscript.Echo "Notepad was started with a process ID of " _
& objOutParams.ProcessId
Else
Wscript.Echo "Notepad could not be started due to error " & _
objOutParams.ReturnValue
End If
以下过程介绍如何使用 C++ 调用提供程序方法。
若要使用 C++ 调用提供程序方法
连接到 WMI。
若要在 WMI 中调用方法,首先必须与 WMI 命名空间建立有效连接。 有关详细信息,请参阅使用 C++ 创建 WMI 应用程序和为 WMI 应用程序初始化 COM。
以下示例演示如何连接到 WMI。 有关 WMI 提供程序调用中安全问题的详细信息,请参阅维护 WMI 安全。
HRESULT hr = CoInitialize(0);
hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLocator);
hr = pLocator->ConnectServer(path, NULL, NULL,
NULL, 0, NULL, NULL, &pNamespace);
调用 IWbemServices::GetObject 以检索要调用的方法的类定义。
GetObject方法返回一个指向类定义的 IWbemClassObject 指针。
hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
对于需要输入参数的方法,请调用 IWbemClassObject::GetMethod 方法以获取输入参数类对象。
GetMethod 返回一个指向输入参数类的 IWbemClassObject 指针。
hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
- 通过调用 IWbemClassObject::SpawnInstance 方法生成输入参数类的实例。
hr = pInClass->SpawnInstance(0, &pInInst);
- 通过调用 IWbemClassObject::Put 方法设置输入参数类的属性。
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal= SysAllocString(L"hello");
hr = pInInst->Put(ArgName, 0, &var, 0);
VariantClear(&var);
通过调用 IWbemServices::ExecMethod 或 IWbemServices::ExecMethodAsync 调用该方法。
对于 ExecMethod,WMI 返回调用中的任何输出参数。 对于 ExecMethodAsync,WMI 通过调用 IWbemObjectSink 返回任何输出参数。 有关详细信息,请参阅调用方法。
hr = pNamespace->ExecMethod(ClassPath, MethodName, 0, NULL, pInInst, &pOutInst, NULL);
以下代码是调用提供程序方法的完整示例。
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int main(int iArgCnt, char ** argv)
{
IWbemLocator *pLocator = NULL;
IWbemServices *pNamespace = 0;
IWbemClassObject * pClass = NULL;
IWbemClassObject * pOutInst = NULL;
IWbemClassObject * pInClass = NULL;
IWbemClassObject * pInInst = NULL;
BSTR path = SysAllocString(L"root\\default");
BSTR ClassPath = SysAllocString(L"TestMeth");
BSTR MethodName = SysAllocString(L"Echo");
BSTR ArgName = SysAllocString(L"sInArg");
BSTR Text;
// Initialize COM and connect to WMI.
HRESULT hr = CoInitialize(0);
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLocator);
hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace);
// Get the class object for the method definition.
hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
// Get the input-argument class object and
// create an instance.
hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
hr = pInClass->SpawnInstance(0, &pInInst);
// Set the property.
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal= SysAllocString(L"hello");
hr = pInInst->Put(ArgName, 0, &var, 0);
VariantClear(&var);
// Call the method.
hr = pNamespace->ExecMethod(ClassPath, MethodName, 0, NULL, pInInst, &pOutInst, NULL);
// Display the results. Note that the return
// value is in the property "ReturnValue"
// and the returned string is in the
// property "sOutArg".
hr = pOutInst->GetObjectText(0, &Text);
printf("\nThe object text is:\n%S", Text);
// Free up resources.
SysFreeString(path);
SysFreeString(ClassPath);
SysFreeString(MethodName);
SysFreeString(ArgName);
SysFreeString(Text);
pClass->Release();
pInInst->Release();
pInClass->Release();
pOutInst->Release();
pLocator->Release();
pNamespace->Release();
CoUninitialize();
printf("Terminating normally\n");
return 0;
}
相关主题