Feld Abfrage

  • Hallo Leute ich steh vor einem kleinen Problem.
    Ich hab ein Script mit dem ich einige Daten von dem Computer auslese über die WMI.

    [autoit]



    $objWMIService = ObjGet("winmgmts:\\" & $cI_Compname & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) Then
    For $objItem In $colItems
    ReDim $aOSInfo[UBound($aOSInfo) + 1][60]
    $aOSInfo[$i][0] = $objItem.Name
    ...

    [/autoit]

    Jetzt bekomme ich aber folgenden Fehler bei einem Computer (Anhang). Ich denke der Fehler entsteht, da das "$objItem.Name" vl. nicht vorhanden ist.
    Wie kann ich dies am besten überprüfen, damit ich den Fehler nicht mehr bekomme bzw der Mitarbeiter davon nichts mitbekommt?

    Vielen lieben dank

  • Der Fehler ensteht, da du versuchst auf ein Arrayelement zuzugreifen, das nicht existiert. Beispielsweise hast du einen Array mit 5 möglichen einträgen, und versuchst an Position 6 einen Eintrag zu erstellen.

    [autoit]

    $aOSInfo[$i][0] = ...

    [/autoit]

    Du nutzt zwar ReDim, aber anscheinend nicht korrekt.
    - Wo ist $i definiert?
    - Ist $i wirklich zu jeder Zeit kleiner als Ubound($aOSInfo) ?
    - Ist $i größer als 0?

  • Erstmals danke für die Antwort.

    Hier wäre der ganze Code dieser Funktion:

    [autoit]


    Func _ComputerGetOSs(ByRef $aOSInfo)
    Local $colItems, $objWMIService, $objItem
    Dim $aOSInfo[1][60], $i = 1

    $objWMIService = ObjGet("winmgmts:\\" & $cI_Compname & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) Then
    For $objItem In $colItems
    ReDim $aOSInfo[UBound($aOSInfo) + 1][60]
    $aOSInfo[$i][0] = $objItem.Name
    $aOSInfo[$i][9] = $objItem.CSDVersion
    $aOSInfo[$i][46] = $objItem.SerialNumber
    $aOSInfo[$i][58] = $objItem.Version
    ;Hier sind natürlich noch andere Objekte (0-60) aber das wäre hier zulang
    $i += 1
    Next
    $aOSInfo[0][0] = UBound($aOSInfo) - 1
    If $aOSInfo[0][0] < 1 Then
    SetError(1, 1, 0)
    EndIf
    Else
    SetError(1, 2, 0)
    EndIf
    EndFunc ;_ComputerGetOSs

    [/autoit]

    und die Abfrage schaut so aus:

    [autoit]


    Dim $os
    _ComputerGetOSs($os)
    If @error Then
    $error = @error
    $extended = @extended
    Switch $extended
    Case 1
    _mysql_errorMSG("Windows" & $ERR_NO_INFO)
    Case 2
    _mysql_errorMSG("Windows" & $ERR_NOT_OBJ)
    EndSwitch
    EndIf
    For $i = 1 To $os[0][0] Step 1
    $comp_win_name = $os[$i][0]
    $comp_win_version = $os[$i][58]
    $comp_win_sp = $os[$i][9]
    $comp_win_oem = $os[$i][46]
    Next

    [/autoit]

    Somit dürfte ich ja eigentlich kein Fehler mit dem $i bekommen... da die Abfrage nur solange geht bis das array zuende ist oder!?

    Aber ich könnte vorher ja noch überprüfen ob das Array existiert bzw eines ist mittels isArray
    Gibt es auch eine Funktion mit der ich überprüfen kann ob der KEY existiert? in php geht das mittels array_key_exists.
    Duchsuch gerade die reference list aber hab bis jetzt noch nichts gefunden

    Einmal editiert, zuletzt von ParTy (14. Juni 2011 um 11:13)

  • [autoit]

    ReDim $aOSInfo[UBound($aOSInfo) + 1][60]
    ;[...]
    ;Hier sind natürlich noch andere Objekte (0-60) aber das wäre hier zulang

    [/autoit]


    Der höchste setzbare Index wäre nach deiner Initialisierung [59] und nicht [60] da die 2. Dimension nur 60 Elemente umfassen darf und die Zählung bei 0 beginnt.
    Wenn das nicht das Problem war dann beschreib mal lieber was du wie in welcher Form herausbekommen willst.

  • Also auf Anhieb sehe ich da keinen Fehler im Code, vielleicht hab ich ihn auch einfach übersehen. Das einzige was mir auffällt, ist dein Kommentar hier:

    ;Hier sind natürlich noch andere Objekte (0-60) aber das wäre hier zulang

    Du weißt schon, dass - mal angenommen du erstellst $aOSInfo[5][60] - ein Zugriff auf z.B. $aOSInfo[1][60] zum Crash führt? Das letzte Element ist dann ja entsprechend $aOSInfo[1][59], weil der Arrayindex bei 0 beginnt.


    (Zu deiner zweiten Frage: Du kannst doch überprüfen, was dir Ubound() zurückgibt. Immerhin bekommst du dadurch die Größe des Arrays zurück. Alle Elemente von 0 bis Ubound() - 1 existieren.)

  • Anstatt manuell mit solch großen Arrays zu hantieren kann man auch etwas anders an die Sache herangehen.
    Wenn ich so halbwegs verstanden haben sollte was du erreichen willst wäre folgendes mal ein Alternativvorschlag:

    Spoiler anzeigen
    [autoit]

    Global $cI_Compname = "localhost"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $a_OSInfos = GetOSInfos($cI_Compname)

    [/autoit] [autoit][/autoit] [autoit]

    ; ---------- alle gefundenen OS einzeln durchgehen:
    For $i = 1 To $a_OSInfos[0]
    $o_Dict = $a_OSInfos[$i]

    [/autoit] [autoit][/autoit] [autoit]

    ; Beispiel zum einzelnen Zugriff auf Werte:
    MsgBox(0, "OSArchitecture", $o_Dict("OSArchitecture") )
    MsgBox(0, "OSLanguage", $o_Dict("OSLanguage") )

    [/autoit] [autoit][/autoit] [autoit]

    ; Beispiel um alle Werte anzuzeigen:
    ConsoleWrite("------- " & $o_Dict("Name") & " ----------- " & @CRLF)
    For $x In $o_Dict.Keys
    ConsoleWrite(@TAB & $x & ":" & @TAB & $o_Dict($x) & @CRLF)
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Funktion gibt ein Array von Dictionarys zurück
    ; Jedes einzelne Dictionary enthält die Informationen zu einem gefundenen OS
    Func GetOSInfos(Const $s_CmpName)
    ; by AspirinJunkie
    Local $a_OSs[1] = [0], $o_DictTempTemp
    Local Const $o_WMI = ObjGet("winmgmts:\\" & $s_CmpName & "\root\CIMV2")

    [/autoit] [autoit][/autoit] [autoit]

    For $i In $o_WMI.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 48)
    $o_DictTemp = ObjCreate('Scripting.Dictionary')
    For $x In $i.Properties_()
    $o_DictTemp($x.Name) = $x.Value
    Next
    ReDim $a_OSs[UBound($a_OSs) + 1]
    $a_OSs[0] += 1
    $a_OSs[$a_OSs[0]] = $o_DictTemp
    Next
    Return $a_OSs
    EndFunc ;==>GetOSInfos

    [/autoit]
  • @ AspirinJunkie danke ... dies ist natürlich um einiges schöner
    SEuBo ... ups mein Fehler. Das Array geht eh nur bis 59 das kommentar hab ich nur schnell schnell für das Forum geschrieben und nicht nachgedacht.

    werde heut am abend mal eine überprüfung über Ubound() machen und dann schauen was mir das ganze liefert.

    Danke in der zwischenzeit... habt mir auf jedenfall weitergeholfen