none
How to use WmiMonitorBrightnessMethods class to set monitor brightness?

    Question

  • Hello,

     

    I can't put the second parameter of WmiSetBrightness(uint8 Brightness, uint64 Timeout) method of

    WmiMonitorBrightnessMethods class.

    Here is the code that I am using:

    HRESULT hr;

    BSTR ClassName = SysAllocString(L"WmiMonitorBrightnessMethods");

    BSTR MethodName = SysAllocString(L"WmiSetBrightness");

    IWbemClassObject* pClass = NULL;

    hr = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);

    IWbemClassObject* pInParamsDefinition = NULL;

    hr = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL);

    IWbemClassObject* pClassInstance = NULL;

    hr = pInParamsDefinition->SpawnInstance(0, &pClassInstance);

     

    VARIANT varCommand;

    VariantInit(&varCommand);

    V_VT(&varCommand) = VT_UI1;

    V_UI1(&varCommand) = Brightness;

    hr = pClassInstance->Put(L"Brightness", 0, &varCommand, 0);

    VariantClear(&varCommand);

    V_VT(&varCommand) = VT_UI8;

    V_UI8(&varCommand) = Timeout;

    hr = pClassInstance->Put(L"Timeout", 0, &varCommand, 0);

     

    IWbemClassObject* pOutParams = NULL;

    hr = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);

    The pClassInstance->Put(L"Timeout", 0, &varCommand, 0) always return 0x80041005

    (WBEM_E_TYPE_MISMATCH).

     

    Is WmiSetBrightness method has some problem? Or my C++ code has problem?

    Thanks!

     

     

    Wednesday, May 16, 2007 10:11 AM

All replies

  • Dear Terry Wu,

    You could pass WBEM_E_TYPE_MISMATCH (0x80041005) by using VT_I4 on Timeout property.

    But then I face problem: the program returns WBEM_E_INVALID_METHOD_PARAMETERS  (0x8004102F) on the call of

    hr = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);

     

    I set 0 for "Brightness" and 1000 for "Timeout". (In fact , I have had try many other values.)

     

      Such a notebook could use "Windows Mobility Center" in Control Panel to adjust the brightness, so I think that the ACPI BIOS

    had already added the required ASL code.

     

    Is there any suggestion?  Smile  Help me.  Thank you very much.

    Thursday, May 17, 2007 9:31 AM
  •  

    Dear Pinky,

     

    Thanks for your suggestion!

    I found a method to  put "Timeout" property. It also can pass WBEM_E_TYPE_MISMATCH issue.

    Here is the code:

    VariantInit(&varCommand);

    V_VT(&varCommand) = VT_BSTR;

    V_BSTR(&varCommand) = SysAllocString(L"1000");

    hr = pClassInstance->Put(L"Timeout", 0, &varCommand, 0);

    But I still have the same problem that  pSvc->ExecMethod always returns WBEM_E_INVALID_METHOD_PARAMETERS  (0x8004102F). Now, I am working on this issue. If I have the answer, I will post it for you.

     

    Thanks!

    Best regards.

    Thursday, May 17, 2007 11:50 AM
  • Hi Terry,

    Before you check ExecMethod  error, I think you should check MSDN one more time.

    http://msdn2.microsoft.com/en-us/library/aa394549.aspx

     

    Code Snippet
    uint32 WmiSetBrightness(
      uint8 Brightness,
      uint64 Timeout
    );

     

    Those two parameters type are uint8 and uint64, matbe this is why you always got result of "WBEM_E_INVALID_METHOD_PARAMETER"

    But until now, I still could not get any idea to fix your current problem.

     

    I would let you know if I found the solution.

    Friday, May 18, 2007 10:08 AM
  • Hi Evan & Terry,

     

    I have the same problem with yours.

    Is this Microsoft Bugs or have solutions to fix it?

     

    Best regards,

    Ted

    Thursday, December 13, 2007 10:00 AM
  • This WMI method drives me crazy.

     

    First the sequence on the net and on MSDN is different(Timeout first or brightness first)

     

    And then the Variant type, in MSDN it's UINT64, but in WDK the mof says it UINT32.

     

    Code Block

      [WmiMethodId(1),
       Implemented,
       Description("Set current brightness setting"):amended
      ] void WmiSetBrightness([in,
                               Description("Timeout - in seconds"):amended
                              ] uint32 Timeout,
                              [in,
                               Description("Brightness - percentage"):amended
                              ] uint8 Brightness);

     

     

    And although I'm not familiar with WMI, from what I saw in MSDN, the Put method do some cast on it's own.  So if it says S_OK it should be OK with the parameter?

     

    Maybe the later 0x8004102F error is not Type problem?

     

    If this is not going to work, the last way to go back to IOCTL to do this.

     

    Regards,

    priv

    Tuesday, January 22, 2008 6:18 AM
  • Here is a sample code that can work fine in my site. You can try.

     

    Code Snippet


    //
    // **************************************************************************

    #include <objbase.h>
    #include <windows.h>                                    
    #include <stdio.h>
    #include <wbemidl.h>
    #include <comdef.h>

    //***************************************************************************
    //
    // main
    //
    // Purpose: Initialized Ole, call the method, and cleanup.
    //
    //***************************************************************************

    BOOL g_bInProc = FALSE;
     
    int main(int iArgCnt, char ** argv)
    {
        IWbemLocator *pLocator = NULL;
        IWbemServices *pNamespace = 0;
        IWbemClassObject * pClass = NULL;
        IWbemClassObject * pInClass = NULL;
        IWbemClassObject * pInInst = NULL;
     IEnumWbemClassObject *pEnum = NULL;
     HRESULT hr = S_OK;
     
        BSTR path = SysAllocString(L"root\\wmi");
        BSTR ClassPath = SysAllocString(L"WmiMonitorBrightnessMethods");
        BSTR MethodName = SysAllocString(L"WmiSetBrightness");
        BSTR ArgName0 = SysAllocString(L"Timeout");
     BSTR ArgName1 = SysAllocString(L"Brightness");
     BSTR bstrQuery = SysAllocString(L"Select * from WmiMonitorBrightnessMethods");

     if (!path || ! ClassPath || !MethodName || ! ArgName0)
     {
      printf("SysAllocString failed. Out of memory.\n");
      goto cleanup;
     }
     

        // Initialize COM and connect up to CIMOM

        hr = CoInitialize(0);
     if (FAILED(hr))
     {
         printf("CoInitialize returned 0x%x:", hr);
      goto cleanup;
     }

     //  NOTE:
     //  When using asynchronous WMI API's remotely in an environment where the "Local System" account
     //  has no network identity (such as non-Kerberos domains), the authentication level of
     //  RPC_C_AUTHN_LEVEL_NONE is needed. However, lowering the authentication level to
     //  RPC_C_AUTHN_LEVEL_NONE makes your application less secure. It is wise to
     // use semi-synchronous API's for accessing WMI data and events instead of the asynchronous ones.

        hr = CoInitializeSecurity ( NULL, -1, NULL, NULL,
         RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL,
         EOAC_SECURE_REFS, //change to EOAC_NONE if you change dwAuthnLevel to RPC_C_AUTHN_LEVEL_NONE
         NULL );
     if (FAILED(hr))
     {
         printf("CoInitializeSecurity returned 0x%x:", hr);
      goto cleanup;
     }

        hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
                IID_IWbemLocator, (LPVOID *) &pLocator);
     if (FAILED(hr))
     {
         printf("CoCreateInstance returned 0x%x:", hr);
      goto cleanup;
     }
        hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace);
        printf("\n\nConnectServer returned 0x%x:", hr);
        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;


     hr = CoSetProxyBlanket(pNamespace,
      RPC_C_AUTHN_WINNT,
      RPC_C_AUTHZ_NONE,
      NULL,
      RPC_C_AUTHN_LEVEL_PKT,
      RPC_C_IMP_LEVEL_IMPERSONATE,
      NULL,
      EOAC_NONE
      );

        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;


      hr =pNamespace->ExecQuery(_bstr_t(L"WQL"), //Query Language
      bstrQuery, //Query to Execute
      WBEM_FLAG_RETURN_IMMEDIATELY, //Make a semi-synchronous call
      NULL, //Context
      &pEnum //Enumeration Interface
      );

        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;
     
      hr = WBEM_S_NO_ERROR;

      while (WBEM_S_NO_ERROR == hr)
      {

      ULONG ulReturned;
      IWbemClassObject *pObj;
      DWORD retVal = 0;

      //Get the Next Object from the collection
      hr = pEnum->Next(WBEM_INFINITE, //Timeout
      1, //No of objects requested
      &pObj, //Returned Object
      &ulReturned //No of object returned
      );

        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

        // Get the class object
        hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
        printf("\nGetObject returned 0x%x:", hr);
        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

        // Get the input argument and set the property
        hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
        printf("\nGetMethod returned 0x%x:", hr);
        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

        hr = pInClass->SpawnInstance(0, &pInInst);
        printf("\nSpawnInstance returned 0x%x:", hr);
        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

     VARIANT var1;
     VariantInit(&var1);

     V_VT(&var1) = VT_BSTR;
     V_BSTR(&var1) = SysAllocString(L"0");
     hr = pInInst->Put(ArgName0, 0, &var1, CIM_UINT32); //CIM_UINT64

     //var1.vt = VT_I4;
     //var1.ullVal = 0;
     //   hr = pInInst->Put(ArgName0, 0, &var1, 0);
     printf("\nPut ArgName0 returned 0x%x:", hr);
     VariantClear(&var1);
     if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

     VARIANT var;
     VariantInit(&var);

     V_VT(&var) = VT_BSTR;
     V_BSTR(&var) = SysAllocString(L"100");
     hr = pInInst->Put(ArgName1, 0, &var, CIM_UINT8); 

     //var.vt=VT_UI1;
     //var.uiVal = 100;
     //hr = pInInst->Put(ArgName1, 0, &var, 0); 
     VariantClear(&var);
         printf("\nPut ArgName1 returned 0x%x:", hr);
     if(hr != WBEM_S_NO_ERROR)
      goto cleanup;
        // Call the method

     VARIANT pathVariable;
     VariantInit(&pathVariable);

     hr = pObj->Get(_bstr_t(L"__PATH"),0,&pathVariable,NULL,NULL);
     printf("\npObj Get returned 0x%x:", hr);
     if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

     hr =pNamespace->ExecMethod(pathVariable.bstrVal, MethodName, 0, NULL, pInInst,NULL, NULL);
     VariantClear(&pathVariable);
        printf("\nExecMethod returned 0x%x:", hr);
        if(hr != WBEM_S_NO_ERROR)
      goto cleanup;

    }//End While

     printf("Terminating normally\n");

     // Free up resources
    cleanup:

        SysFreeString(path);
        SysFreeString(ClassPath);
        SysFreeString(MethodName);
        SysFreeString(ArgName0);
     SysFreeString(ArgName1);
     SysFreeString(bstrQuery);

     if (pClass)
      pClass->Release();
     if (pInInst)
      pInInst->Release();
     if (pInClass)
      pInClass->Release();
     if (pLocator)
      pLocator->Release();
     if (pNamespace)
      pNamespace->Release();
        CoUninitialize();
        return 0;
    }

     

     

     

    Wednesday, January 30, 2008 1:46 AM
  • The setting of the brightness works fine on a laptop or notebook, but failes on a desktop (naturally, because these monitors do not have the physical hardware to adjust the brightness.

    Is there any way of checking a WMI method or event weather or not it can be used? This is a big issue in my project, because my program adjusts the power setting.

    The code below, could be an answer, but on my LAPTOP (Windows7 ultimate) it does not give the right machinetype

     

     

    public enum ChassisTypes

    {

    Other = 1,

    Unknown,

    Desktop,

    LowProfileDesktop,

    PizzaBox,

    MiniTower,

    Tower,

    Portable,

    Laptop,

    Notebook,

    Handheld,

    DockingStation,

    AllInOne,

    SubNotebook,

    SpaceSaving,

    LunchBox,

    MainSystemChassis,

    ExpansionChassis,

    SubChassis,

    BusExpansionChassis,

    PeripheralChassis,

    StorageChassis,

    RackMountChassis,

    SealedCasePC

    }

     

    public static ChassisTypes GetCurrentChassisType()

    {

     

    ManagementClass systemEnclosures = new ManagementClass("Win32_SystemEnclosure");

     

    foreach (ManagementObject obj in systemEnclosures.GetInstances())

    {

     

    foreach (int i in (UInt16[])(obj["ChassisTypes"]))

    {

     

    if (i > 0 && i < 25)

    {

     

    return (ChassisTypes)i;

    }

    }

    }

     

    return ChassisTypes.Unknown;

    }

    Wednesday, May 19, 2010 6:24 PM