@zeironjj_jogo

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

パラメーターの設定に失敗する

解決したいこと

PowerShellからモニターの明るさを変えられることを知って実際に動いたので、Windows APIを使って下のようにモニターの明るさを変えようとしています。

$methods = Get-CimInstance -NameSpace "ROOT\WMI" -ClassName "WmiMonitorBrightnessMethods"
Invoke-CimMethod -InputObject $methods -MethodName "WmiSetBrightness" -Arguments @{ Timeout=5; Brightness=$xxx }

ですが、下のメソッドを呼び出そうと引数の設定をするところで、パラメーターTimeoutの設定に失敗してしまいます。

uint32 WmiSetBrightness(
    uint32 Timeout
    uint8 Brightness
);

発生している問題・エラー

パラメーターTimeoutを設定しようとすると、型を正しく設定したはずが「型が合っていない」という値が返ってきます。
cim型がuint32なのでVARIANTの型はVT_UI4で合っていると思うのですが...

もう一つのパラメーターBrightnessは問題なく設定できているようです。

VariantInit(&vTimeout);
vTimeout.vt = VT_UI4;
vTimeout.ulVal = 5;
// WBEM_E_TYPE_MISMATCH(0x80041005)が返ってくる
hr = pParam->Put(L"Timeout", 0, &vTimeout, CIM_UINT32);

VariantInit(&vBrightness);
vBrightness.vt = VT_UI1;
vBrightness.bVal = level;
// こっちは成功する(S_OK)
hr = pParam->Put(L"Brightness", 0, &vBrightness, CIM_UINT8);

該当するソースコード

HRESULT SetBrightness(IWbemServices* pSvc, BYTE level)
{
	HRESULT hr;
	IEnumWbemClassObject* pEnum = nullptr;
	IWbemClassObject* pObj = nullptr, *pParamCls = nullptr, *pParam = nullptr, *pMethodsCls = nullptr;
	ULONG received;
	VARIANT vPath, vTimeout, vBrightness;

	hr = pSvc->ExecQuery(
		BSTR(L"WQL"),
		BSTR(L"SELECT * FROM WmiMonitorBrightnessMethods"),
		WBEM_FLAG_FORWARD_ONLY,
		nullptr,
		&pEnum
	);
	if (FAILED(hr))
	{
		~~~
	}

	while ((hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &received)) == WBEM_S_NO_ERROR && received)
	{
		VARIANT vActive;
		VariantInit(&vActive);

		hr = pObj->Get(L"Active", 0, &vActive, nullptr, nullptr);
		if (FAILED(hr))
		{
			~~~
		}

		wprintf(L"Active = %d\n", vActive.boolVal);
		if (vActive.boolVal == VARIANT_TRUE)
		{
			VariantClear(&vActive);
			break;
		}

		VariantClear(&vActive);
		pObj->Release();
		pObj = nullptr;
	}

	VariantInit(&vPath);
	hr = pObj->Get(L"__PATH", 0, &vPath, nullptr, nullptr);
	if (FAILED(hr))
	{
		~~~
	}

	hr = pSvc->GetObjectW(
		BSTR(L"WmiMonitorBrightnessMethods"),
		0,
		nullptr,
		&pMethodsCls,
		nullptr
	);
	if (FAILED(hr))
	{
		~~~
	}

	hr = pMethodsCls->GetMethod(
		L"WmiSetBrightness",
		0,
		&pParamCls,
		nullptr
	);
	if (FAILED(hr))
	{
		~~~
	}

	hr = pParamCls->SpawnInstance(0, &pParam);
	if (FAILED(hr))
	{
		~~~
	}

	VariantInit(&vTimeout);
	vTimeout.vt = VT_UI4;
	vTimeout.ulVal = 5;
	hr = pParam->Put(
		L"Timeout",
		0,
		&vTimeout,
		CIM_UINT32
	);
	if (FAILED(hr))
	{
		~~~
	}

	VariantInit(&vBrightness);
	vBrightness.vt = VT_UI1;
	vBrightness.bVal = level;
	hr = pParam->Put(
		L"Brightness",
		0,
		&vBrightness,
		CIM_UINT8
	);
	if (FAILED(hr))
	{
		~~~
	}
    // 以下略

自分で試したこと

hr = pParam->Get(L"Timeout", 0, &vTimeout, &type, &flavor);
// vTimeout = NULL, type = 19(CIM_UINT32), flavor = 32

・取得は出来るのでTimeoutというパラメーターは確かに存在するよう。

Putの後にGetErrorInfoでエラーを取得しようとしてもS_FALSE(返すエラーオブジェクトが存在しない)が返ってくる。

TimeoutPutせず、ExecMethodに渡すとWBEM_E_INVALID_PARAMETER(0x80041008)が返ってくる。

0 likes

1Answer

cim型がuint32なのでVARIANTの型はVT_UI4で合っていると思うのですが...

CIM_UINT32は、VT_I4の場合もあるようです。
VT_I4に変えてみたらどうでしょうか。

- vTimeout.vt = VT_UI4;
+ vTimeout.vt = VT_I4;
1Like

Comments

  1. @zeironjj_jogo

    Questioner

    回答ありがとうございます。
    VT_I4に変えたところ、うまくいきました!
    ありがとうございました。助かりました。

Your answer might help someone💌