IUPnPService::InvokeAction 方法允许对服务对象调用操作。 此方法有两个输入参数:操作的名称和该操作的输入参数数组。 该方法有两个参数:
- 参数一 - 输入/输出参数:该操作的输出参数数组。
- 参数 2 - 输出参数:返回值。
该方法会导致在设备上调用操作。 如果操作导致设备的状态变量发生更改,设备将生成事件通知。
VBScript 示例
以下 VBScript 代码示例对服务对象调用两个操作。 第一个操作 GetTrackInfo 采用一个输入参数,一个跟踪编号。 GetTrackInfo 操作将跟踪长度作为返回值返回。 该操作还具有一个输出参数,如果该方法返回成功,则包含曲目标题。
调用 GetTrackInfo 操作后,该示例将调用 Play 操作,该操作不采用任何参数。 但是,由于 InvokeAction 的语法需要输入参数和输出参数的数组,因此该示例必须创建一个空数组( emptyArgs)且没有元素。 该示例将此数组传递给输入和输出参数的 InvokeAction ,以及操作的名称。
Dim returnVal
Dim outArgs(1)
Dim args(1)
args(0) = 3
returnVal = service.InvokeAction("GetTrackInfo", args, outArgs)
'return Val now contains the track length
'and outArgs(0) contains the track title
Dim emptyArgs(0)
returnVal = service.InvokeAction("Play", emptyArgs, emptyArgs)
'returnVal indicates if the action was successful
C++ 示例
以下示例定义一个 C++ 函数,该函数调用不带参数的操作。 由于 InvokeAction 需要传入参数的 SAFEARRAY ,因此此示例将创建一个空 的 SAFEARRAY。 由于此操作不返回值或具有输出参数,本示例将忽略传递给 InvokeAction 的最后两个 VARIANT 值。
如果操作导致设备的状态变量发生更改,设备将生成事件通知。
#include <windows.h>
#include <upnp.h>
#include <iostream>
#include <iomanip>
#pragma comment(lib, "oleaut32.lib")
using namespace std;
void InvokePlay(IUPnPService * pService)
{
HRESULT hr;
BSTR bstrActionName;
bstrActionName = SysAllocString(L"Play");
if (bstrActionName)
{
SAFEARRAYBOUND rgsaBound[1];
SAFEARRAY * psa = NULL;
rgsaBound[0].lLbound = 0;
rgsaBound[0].cElements = 0;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
if (psa)
{
LONG lStatus;
VARIANT varInArgs;
VariantInit(&varInArgs);
varInArgs.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&varInArgs) = psa;
hr = pService->InvokeAction(bstrActionName,
varInArgs,
NULL,
NULL);
if (SUCCEEDED(hr))
{
wcout << L"Action invoked successfully\n";
}
else
{
wcerr << L"Failed to invoke action - HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
SafeArrayDestroy(psa);
}
else
{
wcerr << L"Failed to create safe array\n";
}
SysFreeString(bstrActionName);
}
else
{
wcerr << L"Failed to allocate action name string\n";
}
}
以下示例调用虚构 的 GetTrackInfo 操作。 它采用跟踪编号作为参数,以返回值的形式返回跟踪长度,并在输出参数中返回跟踪标题。 该代码与上一个示例类似,只不过该代码不会创建输入参数的空 SAFEARRAY ,而是插入包含跟踪编号的 VARIANT 。 如果 InvokeAction 返回成功,此示例将检查返回值和输出参数数组。
#include <windows.h>
#include <upnp.h>
#include <iostream>
#include <iomanip>
#pragma comment(lib, "oleaut32.lib")
using namespace std;
void InvokeGetTrackInfo(IUPnPService * pService)
{
HRESULT hr;
BSTR bstrActionName;
bstrActionName = SysAllocString(L"GetTrackInfo");
if (bstrActionName)
{
SAFEARRAYBOUND rgsaBound[1];
SAFEARRAY * psa = NULL;
rgsaBound[0].lLbound = 0;
rgsaBound[0].cElements = 1;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
if (psa)
{
long rgIndices[1];
VARIANT varTrackNum;
rgIndices[0] = 0;
VariantInit(&varTrackNum);
varTrackNum.vt = VT_I4;
// An arbitrary track is chosen (track 3)
V_I4(&varTrackNum) = 3;
hr = SafeArrayPutElement(psa,
rgIndices,
(void *) &varTrackNum);
VariantClear(&varTrackNum);
if (SUCCEEDED(hr))
{
LONG lStatus;
VARIANT varInArgs;
VARIANT varOutArgs;
VARIANT varReturnVal;
VariantInit(&varInArgs);
VariantInit(&varOutArgs);
VariantInit(&varReturnVal);
varInArgs.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&varInArgs) = psa;
hr = pService->InvokeAction(bstrActionName,
varInArgs,
&varOutArgs,
&varReturnVal);
if (SUCCEEDED(hr))
{
SAFEARRAY * psaOutArgs = NULL;
VARIANT varTrackTitle;
psaOutArgs = V_ARRAY(&varOutArgs);
VariantInit(&varTrackTitle);
rgIndices[0] = 0;
hr = SafeArrayGetElement(psaOutArgs,
rgIndices,
(void *)&varTrackTitle);
if (SUCCEEDED(hr))
{
wcout << L"Action invoked successfully\n"
<< L"\tTrack Length == "
<< V_I4(&varReturnVal) << L"\n"
<< L"\tTrack Title == "
<< V_BSTR(&varTrackTitle) << L"\n";
}
else
{
wcerr << L"Failed to get array element -"
<< L" HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
VariantClear(&varTrackTitle);
VariantClear(&varReturnVal);
VariantClear(&varOutArgs);
}
else
{
wcerr << L"Failed to invoke action - HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
}
else
{
wcerr << L"Failed to insert argument into array - "
<< L"HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
SafeArrayDestroy(psa);
}
else
{
wcerr << L"Failed to create safe array\n";
}
SysFreeString(bstrActionName);
}
else
{
wcerr << L"Failed to allocate action name string\n";
}
}