PureBasic Forum
https://www.purebasic.fr/english/

WMI
https://www.purebasic.fr/english/viewtopic.php?f=12&t=64822
Page 1 of 2

Author:  nco2k [ Tue Feb 09, 2016 11:45 pm ]
Post subject:  WMI

i needed wmi to return some system internal data, so i wrote this little function from scratch. it works in ascii-, unicode-, 32bit- and 64bit-mode and supports the proper "SELECT X FROM Y WHERE Z" syntax. you can write "SELECT A, B, C FROM X" to list only the properties you need or you can write "SELECT * FROM X" to list them all.

the function supports almost every type. only one dimensional safe-arrays are supported though. i couldnt find any data that uses multi dimensional safe-arrays, so i didnt have the chance to figure out how they work. i wanted to add support for the #VT_DECIMAL type as well, but also couldnt find any data to play with.

each property entry is separated by #CRLF$:
WMI("SELECT Caption, OSArchitecture FROM Win32_OperatingSystem") returns for example: "Caption=Microsoft Windows 7 Home Premium"+#CRLF$+"OSArchitecture=64-Bit"+#CRLF$

each array entry is separated by #US$:
WMI("SELECT BiosCharacteristics FROM Win32_BIOS") returns for example: "BiosCharacteristics=1"+#US$+"2"+#US$+"3"+#US$+"4"+#US$+"5"+#US$+#CRLF$

have fun!

Code:
;WMI by nco2k for PureBasic 5.41 LTS

EnableExplicit

#RPC_C_AUTHN_WINNT = 10
#RPC_C_AUTHN_LEVEL_CALL = 3
#RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6
#RPC_C_AUTHZ_NONE = 0
#RPC_C_IMP_LEVEL_IMPERSONATE = 3
#RPC_E_CHANGED_MODE = $80010106
#EOAC_NONE = 0
#CLSCTX_INPROC_SERVER = $1
#WBEM_FLAG_ALWAYS = 0
#WBEM_FLAG_RETURN_IMMEDIATELY = 16
#WBEM_FLAG_FORWARD_ONLY = 32
#WBEM_FLAG_NONSYSTEM_ONLY = 64
#WBEM_INFINITE = -1

Structure DECIMAL2
  wReserved.w
  scale.b
  sign.b
  Hi32.l
  Lo64.q
EndStructure

Structure VARIANT2
  vt.w
  wReserved1.w
  wReserved2.w
  wReserved3.w
  StructureUnion
    llVal.q
    lVal.l
    bVal.b
    iVal.w
    fltVal.f
    dblVal.d
    boolVal.w
    bool.w
    scode.l
    cyVal.q
    date.d
    bstrVal.i
    *punkVal.IUnknown
    *pdispVal.IDispatch
    *parray
    *pbVal.BYTE
    *piVal.WORD
    *plVal.LONG
    *pllVal.QUAD
    *pfltVal.FLOAT
    *pdblVal.DOUBLE
    *pboolVal.WORD
    *pbool.WORD
    *pscode.LONG
    *pcyVal.QUAD
    *pdate.DOUBLE
    *pbstrVal.INTEGER
    *ppunkVal.INTEGER
    *ppdispVal.INTEGER
    *pparray.INTEGER
    *pvarVal.VARIANT2
    *byref
    cVal.b
    uiVal.w
    ulVal.l
    ullVal.q
    intVal.l
    uintVal.l
    *pdecVal.DECIMAL2
    *pcVal.BYTE
    *puiVal.WORD
    *pulVal.LONG
    *pullVal.QUAD
    *pintVal.LONG
    *puintVal.LONG
    brecord.VARIANT_BRECORD
    decVal.DECIMAL2
  EndStructureUnion
EndStructure

Import "OleAut32.lib"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    SysAllocString2_(String.p-unicode) As "_SysAllocString"
    SysFreeString2_(*String) As "_SysFreeString"
  CompilerElse
    SysAllocString2_(String.p-unicode) As "SysAllocString"
    SysFreeString2_(*String) As "SysFreeString"
  CompilerEndIf
EndImport

Procedure$ WMI(WQL$)
  Protected Result$, QuerySelect$, QuerySelectIndex, PropertyList$, PropertyListIndex, PropertyListSize, PropertyListElement$, *PropertyArray, PropertyArrayIndex, PropertyArrayOffset.l, PropertyArraySize.l, PropertyArrayDimensions, PropertyArrayElement$, BufferArrayIndex, BufferArrayOffset.l, BufferArraySize.l, BufferArrayDimensions, BufferArrayElement$
  Protected CoInit, *SysRoot, *SysLanguage, *SysQuery, *SysArray, *SysList, ClassObjectSize, iwbemlocator.IWbemLocator, iwbemservices.IWbemServices, ienumwbemclassobject.IEnumWbemClassObject, iwbemclassobject.IWbemClassObject, variant.VARIANT2, VarByte.b, VarWord.w, VarLong.l, VarQuad.q, VarFloat.f, VarDouble.d, *VarString, *VarArray
  If UCase(Left(WQL$, 7)) = "SELECT "
    QuerySelectIndex = FindString(WQL$, " FROM ", 9, #PB_String_NoCase)
    If QuerySelectIndex
      QuerySelect$ = Trim(Mid(WQL$, 8, QuerySelectIndex - 8))
    EndIf
  EndIf
  If QuerySelect$
    CoInit = CoInitializeEx_(0, #COINIT_APARTMENTTHREADED | #COINIT_DISABLE_OLE1DDE)
    If CoInit = #S_OK Or CoInit = #S_FALSE Or CoInit = #RPC_E_CHANGED_MODE
      If CoInitializeSecurity_(0, -1, 0, 0, #RPC_C_AUTHN_LEVEL_PKT_PRIVACY, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE, 0) = #ERROR_SUCCESS And CoCreateInstance_(?CLSID_WbemLocator, 0, #CLSCTX_INPROC_SERVER, ?IID_IWbemLocator, @iwbemlocator) = #ERROR_SUCCESS
        *SysRoot = SysAllocString2_("ROOT\CIMV2")
        If *SysRoot
          If iwbemlocator\ConnectServer(*SysRoot, 0, 0, 0, 0, 0, 0, @iwbemservices) = #ERROR_SUCCESS
            If CoSetProxyBlanket_(iwbemservices, #RPC_C_AUTHN_WINNT, #RPC_C_AUTHZ_NONE, 0, #RPC_C_AUTHN_LEVEL_CALL, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE) = #ERROR_SUCCESS
              *SysLanguage = SysAllocString2_("WQL")
              If *SysLanguage
                *SysQuery = SysAllocString2_(WQL$)
                If *SysQuery
                  If iwbemservices\ExecQuery(*SysLanguage, *SysQuery, #WBEM_FLAG_FORWARD_ONLY | #WBEM_FLAG_RETURN_IMMEDIATELY, 0, @ienumwbemclassobject) = #ERROR_SUCCESS
                    While ienumwbemclassobject\Next(#WBEM_INFINITE, 1, @iwbemclassobject, @ClassObjectSize) = #ERROR_SUCCESS And ClassObjectSize = 1
                      If QuerySelect$ <> "*"
                        PropertyList$ = QuerySelect$+","
                      Else
                        PropertyList$ = ""
                        *PropertyArray = #False
                        If iwbemclassobject\GetNames(0, #WBEM_FLAG_ALWAYS | #WBEM_FLAG_NONSYSTEM_ONLY, 0, @*PropertyArray) = #ERROR_SUCCESS And *PropertyArray
                          PropertyArrayDimensions = SafeArrayGetDim_(*PropertyArray)
                          If PropertyArrayDimensions = 1 And SafeArrayGetLBound_(*PropertyArray, PropertyArrayDimensions, @PropertyArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*PropertyArray, PropertyArrayDimensions, @PropertyArraySize) = #ERROR_SUCCESS
                            For PropertyArrayIndex = PropertyArrayOffset To PropertyArraySize
                              If SafeArrayGetElement_(*PropertyArray, @PropertyArrayIndex, @*SysArray) = #ERROR_SUCCESS And *SysArray
                                PropertyArrayElement$ = PeekS(*SysArray, -1, #PB_Unicode)
                                If PropertyArrayElement$
                                  PropertyList$+PropertyArrayElement$+","
                                EndIf
                                SysFreeString2_(*SysArray)
                              EndIf
                            Next
                          EndIf
                          SafeArrayDestroy_(*PropertyArray)
                        EndIf
                      EndIf
                      If PropertyList$
                        PropertyListSize = CountString(PropertyList$, ",")
                        For PropertyListIndex = 1 To PropertyListSize
                          PropertyListElement$ = Trim(StringField(PropertyList$, PropertyListIndex, ","))
                          If PropertyListElement$
                            *SysList = SysAllocString2_(PropertyListElement$)
                            If *SysList
                              If iwbemclassobject\Get(*SysList, 0, @variant, 0, 0) = #ERROR_SUCCESS
                                Select variant\vt
                                  Case #VT_EMPTY, #VT_NULL, #VT_VOID, #VT_BYREF | #VT_EMPTY, #VT_BYREF | #VT_NULL, #VT_BYREF | #VT_VOID
                                    Result$+PropertyListElement$+"="+#CRLF$
                                  Case #VT_BOOL, #VT_BYREF | #VT_BOOL
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarWord = variant\boolVal
                                    Else
                                      VarWord = variant\pboolVal\w
                                    EndIf
                                    If VarWord
                                      Result$+PropertyListElement$+"=1"+#CRLF$
                                    Else
                                      Result$+PropertyListElement$+"=0"+#CRLF$
                                    EndIf
                                  Case #VT_I1, #VT_BYREF | #VT_I1
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarByte = variant\cVal
                                    Else
                                      VarByte = variant\pcVal\b
                                    EndIf
                                    Result$+PropertyListElement$+"="+Str(VarByte)+#CRLF$
                                  Case #VT_UI1, #VT_BYREF | #VT_UI1
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarByte = variant\bVal
                                    Else
                                      VarByte = variant\pbVal\b
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrU(VarByte, #PB_Byte)+#CRLF$
                                  Case #VT_I2, #VT_BYREF | #VT_I2
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarWord = variant\iVal
                                    Else
                                      VarWord = variant\piVal\w
                                    EndIf
                                    Result$+PropertyListElement$+"="+Str(VarWord)+#CRLF$
                                  Case #VT_UI2, #VT_BYREF | #VT_UI2
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarWord = variant\uiVal
                                    Else
                                      VarWord = variant\puiVal\w
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrU(VarWord, #PB_Word)+#CRLF$
                                  Case #VT_I4, #VT_INT, #VT_BYREF | #VT_I4, #VT_BYREF | #VT_INT
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarLong = variant\lVal
                                    Else
                                      VarLong = variant\plVal\l
                                    EndIf
                                    Result$+PropertyListElement$+"="+Str(VarLong)+#CRLF$
                                  Case #VT_UI4, #VT_UINT, #VT_ERROR, #VT_BYREF | #VT_UI4, #VT_BYREF | #VT_UINT, #VT_BYREF | #VT_ERROR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarLong = variant\ulVal
                                    Else
                                      VarLong = variant\pulVal\l
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrU(VarLong, #PB_Long)+#CRLF$
                                  Case #VT_I8, #VT_CY, #VT_BYREF | #VT_I8, #VT_BYREF | #VT_CY
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarQuad = variant\llVal
                                    Else
                                      VarQuad = variant\pllVal\q
                                    EndIf
                                    Result$+PropertyListElement$+"="+Str(VarQuad)+#CRLF$
                                  Case #VT_UI8, #VT_BYREF | #VT_UI8
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarQuad = variant\ullVal
                                    Else
                                      VarQuad = variant\pullVal\q
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrU(VarQuad, #PB_Quad)+#CRLF$
                                  Case #VT_R4, #VT_BYREF | #VT_R4
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarFloat = variant\fltVal
                                    Else
                                      VarFloat = variant\pfltVal\f
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrF(VarFloat)+#CRLF$
                                  Case #VT_R8, #VT_DATE, #VT_BYREF | #VT_R8, #VT_BYREF | #VT_DATE
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      VarDouble = variant\dblVal
                                    Else
                                      VarDouble = variant\pdblVal\d
                                    EndIf
                                    Result$+PropertyListElement$+"="+StrD(VarDouble)+#CRLF$
                                  Case #VT_LPSTR, #VT_BYREF | #VT_LPSTR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarString = variant\bstrVal
                                    Else
                                      *VarString = variant\pbstrVal\i
                                    EndIf
                                    If *VarString
                                      Result$+PropertyListElement$+"="+PeekS(*VarString, -1, #PB_Ascii)+#CRLF$
                                    Else
                                      Result$+PropertyListElement$+"="+#CRLF$
                                    EndIf
                                  Case #VT_LPWSTR, #VT_BSTR, #VT_BYREF | #VT_LPWSTR, #VT_BYREF | #VT_BSTR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarString = variant\bstrVal
                                    Else
                                      *VarString = variant\pbstrVal\i
                                    EndIf
                                    If *VarString
                                      Result$+PropertyListElement$+"="+PeekS(*VarString, -1, #PB_Unicode)+#CRLF$
                                    Else
                                      Result$+PropertyListElement$+"="+#CRLF$
                                    EndIf
                                  Case #VT_ARRAY | #VT_EMPTY, #VT_ARRAY | #VT_NULL, #VT_ARRAY | #VT_VOID, #VT_BYREF | #VT_ARRAY | #VT_EMPTY, #VT_BYREF | #VT_ARRAY | #VT_NULL, #VT_BYREF | #VT_ARRAY | #VT_VOID
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          BufferArrayElement$+#US$
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_BOOL, #VT_BYREF | #VT_ARRAY | #VT_BOOL
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarWord) = #ERROR_SUCCESS
                                            If VarWord
                                              BufferArrayElement$+"1"+#US$
                                            Else
                                              BufferArrayElement$+"0"+#US$
                                            EndIf
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_I1, #VT_BYREF | #VT_ARRAY | #VT_I1
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarByte) = #ERROR_SUCCESS
                                            BufferArrayElement$+Str(VarByte)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_UI1, #VT_BYREF | #VT_ARRAY | #VT_UI1
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarByte) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrU(VarByte, #PB_Byte)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_I2, #VT_BYREF | #VT_ARRAY | #VT_I2
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarWord) = #ERROR_SUCCESS
                                            BufferArrayElement$+Str(VarWord)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_UI2, #VT_BYREF | #VT_ARRAY | #VT_UI2
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarWord) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrU(VarWord, #PB_Word)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_I4, #VT_ARRAY | #VT_INT, #VT_BYREF | #VT_ARRAY | #VT_I4, #VT_BYREF | #VT_ARRAY | #VT_INT
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarLong) = #ERROR_SUCCESS
                                            BufferArrayElement$+Str(VarLong)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_UI4, #VT_ARRAY | #VT_UINT, #VT_ARRAY | #VT_ERROR, #VT_BYREF | #VT_ARRAY | #VT_UI4, #VT_BYREF | #VT_ARRAY | #VT_UINT, #VT_BYREF | #VT_ARRAY | #VT_ERROR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarLong) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrU(VarLong, #PB_Local)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_I8, #VT_ARRAY | #VT_CY, #VT_BYREF | #VT_ARRAY | #VT_I8, #VT_BYREF | #VT_ARRAY | #VT_CY
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarQuad) = #ERROR_SUCCESS
                                            BufferArrayElement$+Str(VarQuad)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_UI8, #VT_BYREF | #VT_ARRAY | #VT_UI8
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarQuad) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrU(VarQuad, #PB_Quad)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_R4, #VT_BYREF | #VT_ARRAY | #VT_R4
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarFloat) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrF(VarFloat)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_R8, #VT_ARRAY | #VT_DATE, #VT_BYREF | #VT_ARRAY | #VT_R8, #VT_BYREF | #VT_ARRAY | #VT_DATE
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @VarDouble) = #ERROR_SUCCESS
                                            BufferArrayElement$+StrD(VarDouble)+#US$
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_LPSTR, #VT_BYREF | #VT_ARRAY | #VT_LPSTR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @*VarString) = #ERROR_SUCCESS
                                            If *VarString
                                              BufferArrayElement$+PeekS(*VarString, -1, #PB_Ascii)+#US$
                                              SysFreeString2_(*VarString)
                                            Else
                                              BufferArrayElement$+#US$
                                            EndIf
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                  Case #VT_ARRAY | #VT_LPWSTR, #VT_ARRAY | #VT_BSTR, #VT_BYREF | #VT_ARRAY | #VT_LPWSTR, #VT_BYREF | #VT_ARRAY | #VT_BSTR
                                    If variant\vt & #VT_BYREF <> #VT_BYREF
                                      *VarArray = variant\parray
                                    Else
                                      *VarArray = variant\pparray\i
                                    EndIf
                                    If *VarArray
                                      BufferArrayDimensions = SafeArrayGetDim_(*VarArray)
                                      If BufferArrayDimensions = 1 And SafeArrayGetLBound_(*VarArray, BufferArrayDimensions, @BufferArrayOffset) = #ERROR_SUCCESS And SafeArrayGetUBound_(*VarArray, BufferArrayDimensions, @BufferArraySize) = #ERROR_SUCCESS
                                        BufferArrayElement$ = ""
                                        For BufferArrayIndex = BufferArrayOffset To BufferArraySize
                                          If SafeArrayGetElement_(*VarArray, @BufferArrayIndex, @*VarString) = #ERROR_SUCCESS
                                            If *VarString
                                              BufferArrayElement$+PeekS(*VarString, -1, #PB_Unicode)+#US$
                                              SysFreeString2_(*VarString)
                                            Else
                                              BufferArrayElement$+#US$
                                            EndIf
                                          EndIf
                                        Next
                                        Result$+PropertyListElement$+"="+BufferArrayElement$+#CRLF$
                                      EndIf
                                    EndIf
                                EndSelect
                                VariantClear_(variant)
                              EndIf
                              SysFreeString2_(*SysList)
                            EndIf
                          EndIf
                        Next
                      EndIf
                    Wend
                    ienumwbemclassobject\Release()
                  EndIf
                  SysFreeString2_(*SysQuery)
                EndIf
                SysFreeString2_(*SysLanguage)
              EndIf
            EndIf
            iwbemservices\Release()
          EndIf
          SysFreeString2_(*SysRoot)
        EndIf
        iwbemlocator\Release()
      EndIf
      If CoInit <> #RPC_E_CHANGED_MODE
        CoUninitialize_()
      EndIf
    EndIf
  EndIf
  ProcedureReturn Result$
  DataSection
    CLSID_WbemLocator:
      Data.l $4590F811
      Data.w $1D3A, $11D0
      Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24
    IID_IWbemLocator:
      Data.l $DC12A687
      Data.w $737F, $11CF
      Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
  EndDataSection
EndProcedure

;List only the "Caption" and "OSArchitecture" Properties from the "Win32_OperatingSystem" Class
Debug WMI("SELECT Caption, OSArchitecture FROM Win32_OperatingSystem")

;List all Properties (*) from the "Win32_OperatingSystem" Class
Debug WMI("Select * FROM Win32_OperatingSystem")

ps: yes i know i could make it shorter, but i wanted to keep everything in place.

c ya,
nco2k

Author:  RSBasic [ Wed Feb 10, 2016 10:07 am ]
Post subject:  Re: WMI

Wow, very good, thank you for your code! Image

Author:  smacker [ Wed Feb 10, 2016 7:18 pm ]
Post subject:  Re: WMI

Nice, very nice, thanks for posting it :)

Just tried it though and doesn't want to work with some of the newer classes like, for example, MSFT_NetAdapter.

Author:  nco2k [ Wed Feb 10, 2016 9:35 pm ]
Post subject:  Re: WMI

weird. even if you change "Root\Cimv2" to "Root\StandardCimv2" and tweak some parameters, ienumwbemclassobject\Next() keeps failing with #WBEM_E_INVALID_QUERY. no idea how to make those work, sorry. microsoft really likes breaking things. :?

edit: so weird. i restarted my vm and now it works?! :?

simply change line 106 from:
Code:
*SysRoot = SysAllocString2_("Root\Cimv2")
to:
Code:
*SysRoot = SysAllocString2_("Root\StandardCimv2")
if you need data from MSFT_NetAdapter and probably other MSFT_* classes as well.

c ya,
nco2k

Author:  Kwai chang caine [ Thu Feb 11, 2016 2:27 pm ]
Post subject:  Re: WMI

Works great on W7 and v5.23
Thanks for sharing 8)

Author:  kinglestat [ Tue Jan 10, 2017 7:48 am ]
Post subject:  Re: WMI

Thanks, a life saver

Author:  infratec [ Tue Jan 10, 2017 9:53 am ]
Post subject:  Re: WMI

Hi,

nice work!

A feature request (but makes it incompatible :mrgreen: )

Add a string Map() as parameter
and add elements with the PropertyListElement$ as key
and the value as value.
Maybe the number of elements as return value.

Then you can easily access each element from the result.
And for listing you can use ForEach.

Bernd

Author:  infratec [ Tue Jan 10, 2017 11:21 am ]
Post subject:  Re: WMI

:oops: :oops: :oops:

A Map() is impossible because of duplicated keys/properties depending on the select.
And I don't know if a List() with 2 fields makes really sense.

Bernd

Author:  doctorized [ Sat Jan 14, 2017 12:06 pm ]
Post subject:  Re: WMI

Once upon a time, back in 2011 I had made a similar app. Find it here: http://kc2000labs.shadowtavern.com/pb/zips/4.31/WMI_Reader_4.41.zip

Author:  Steving [ Tue Oct 03, 2017 1:42 am ]
Post subject:  Re: WMI

Thanks so much! You are a steely-eyed programming MASTER! :D

Author:  skywalk [ Fri Sep 21, 2018 5:28 pm ]
Post subject:  Re: WMI

Very nice 8)
I have no luck attempting remote PC queries?
I verified my query works with a WMIC command line.
Code:
        *SysRoot = SysAllocString2_("\\MyRemotePC\ROOT\CIMV2")
          *SysUserName = SysAllocString2_("MyAdmin")
          *SysPSWD     = SysAllocString2_("MyAdminPSWD")
          If iwbemlocator\ConnectServer(*SysRoot, *SysUserName, *SysPSWD, 0, 0, 0, 0, @iwbemservices) = #ERROR_SUCCESS
;; I connect OK, but ExecQuery fails?
                  If iwbemservices\ExecQuery(*SysLanguage, *SysQuery, #WBEM_FLAG_FORWARD_ONLY | #WBEM_FLAG_RETURN_IMMEDIATELY, 0, @ienumwbemclassobject) = #ERROR_SUCCESS
;; So, I tried to get the error info but not sure how?
                  Else
                    Protected IErrinfo.IErrorInfo
                    ;GetErrorInfo_(0, @IErrinfo)
                    ;Debug IErrinfo\GetDescription(*SysQuery)
                  EndIf

Author:  nco2k [ Fri Sep 21, 2018 6:12 pm ]
Post subject:  Re: WMI

try adding #CLSCTX_REMOTE_SERVER or simply use #CLSCTX_ALL.

edit: btw you are not using GetDescription() correctly: Retrieving Error Information.
also check if they are doing anything differently: Getting WMI Data from a Remote Computer.

c ya,
nco2k

Author:  skywalk [ Fri Sep 21, 2018 6:47 pm ]
Post subject:  Re: WMI

Yes, but where do I set those flags?
The ConnectServer() was ok.
No mention of these flags in the ExecQuery() docs?

Ok, tried...
Code:
      If CoInitializeSecurity_(0, -1, 0, 0, #RPC_C_AUTHN_LEVEL_PKT_PRIVACY, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE, 0) = #ERROR_SUCCESS And CoCreateInstance_(?CLSID_WbemLocator, 0, #CLSCTX_INPROC_SERVER|#CLSCTX_REMOTE_SERVER, ?IID_IWbemLocator, @iwbemlocator) = #ERROR_SUCCESS

And same result. Fails on iwbemservices\ExecQuery()

Author:  tatanas [ Wed Nov 06, 2019 10:36 am ]
Post subject:  Re: WMI

I just read this topic and I'm also interested in remote connection with credentials.
I can't find the right parameters to use with all those functions and there is no example in PB.
I'm stucked.

Any idea ?

Thanks for your time.

(Oh, and I'm new in PB, it's my first post. I'm coming from Autoit)

Author:  Bitblazer [ Wed Nov 06, 2019 1:59 pm ]
Post subject:  Re: WMI

tatanas wrote:
I just read this topic and I'm also interested in remote connection with credentials.
I can't find the right parameters to use with all those functions and there is no example in PB.
I'm stucked.

Any idea ?

Thanks for your time.

(Oh, and I'm new in PB, it's my first post. I'm coming from Autoit)


Welcome to PureBasic!

You may also want to look here.

Page 1 of 2 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/