merkwürdiger Fehler mit Array.au3

  • Hallo Zusammen,

    ich habe ein kleines Script geschrieben und Infos von PC's auszulesen.

    Bei mir und bei EINEM anderen Kollegen funktioniert das SCript nach dem kompilieren einwandfrei. Bei einem weiteren Kollegen bricht das Script mit der im Anhang gezeigten Fehlermeldung ab. Rufe ich das Script bei mir über unser Verteilungssystem auf (ein einfacher "Call" -Befehl) habe ich die Fehlermeldung auch. Ich habe das Gefühl das das mit der Array.au3 zusammen hängt?

    Hier der Code

    Spoiler anzeigen
    [autoit]


    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Outfile=C:\Temp\Tools\Audit\start_scan.exe
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #cs ----------------------------------------------------------------------------
    AutoIt Version: 3.3.8.1
    Author: AyKay
    Script Function:
    Dieses Script scannt den aktuellen PC und speichert diese Infos in ein Textfile auf dem Server.
    #ce ----------------------------------------------------------------------------
    ; Script Start - Add your code below here
    ;######################################
    ;Includes
    ;######################################
    #include <_NTServices.au3>
    #include <file.au3>
    #include <Array.au3>
    ;######################################
    ;Variablen
    ;######################################
    ;Definition Pfade
    Global $sauditpath
    ;Definition Infos
    Global $sSophosUpdaterVersion, $sSophosVersion, $sFirewallstatus, $iAdminrights, $sAdminrights, $aFile
    Global $re = _getDOSOutput('systeminfo')
    ;Pfade
    $sauditpath = "C:\Temp\Auditfiles\" & @ComputerName
    ;Infos
    $sSysteminfo = $sauditpath & "\systeminfo.txt"
    $sInisave = $sauditpath & "\all.ini"
    DirCreate($sauditpath)
    If FileExists($sBackuppath) Then
    FileDelete($sBackuppath)
    EndIf

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

    ;######################################
    ;Systeminfo auslesen
    ;######################################
    FileOpen($sSysteminfo)
    FileWrite($sSysteminfo, $re)
    FileClose($sSysteminfo)
    _FileReadToArray($sSysteminfo, $aFile)
    For $i = 2 To 33
    $split = StringSplit($aFile[$i], ': ', 1)
    For $j = 1 To UBound($split) -1
    Next
    $split[2] = StringStripWS($split[2], 1)
    IniWrite($sInisave, "Systeminfo", $split[1], $split[2])
    Next
    FileDelete($sSysteminfo)
    ;######################################
    ;Benutzername und Adminrechte auslesen
    ;######################################
    $iAdminrights = IsAdmin()
    If $iAdminrights = "1" Then
    $sAdminrights = "ja"
    Else
    $sAdminrights = "nein"
    EndIf
    $WMI = ObjGet("WinMgmts:root/cimv2")
    $colQuery1 = $WMI.ExecQuery("Select UserName FROM Win32_ComputerSystem")
    For $item In $colQuery1
    $ID = $item.UserName
    Next
    $colQuery2 = $WMI.ExecQuery("Select * FROM Win32_NetworkLoginProfile")
    For $object In $colQuery2
    If $object.Name = $ID Then
    $Name = $object.Fullname
    EndIf
    Next
    IniWrite($sInisave, "User", "Adminrights", $sAdminrights)
    IniWrite($sInisave, "User", "User-ID", @UserName)
    IniWrite($sInisave, "User", "Displayname", $Name)
    ;######################################
    ;Sophos auslesen
    ;######################################
    $sSophosUpdaterVersion = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\***", "DisplayVersion")
    $sSophosVersion = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\***", "DisplayVersion")
    ;FileOpen($sSophosinfo)
    IniWrite($sInisave, "Sophos", "SophosVersion", $sSophosVersion)
    IniWrite($sInisave, "Sophos", "SophosUpdaterVersion", $sSophosUpdaterVersion)
    ;######################################
    ;Services überprüfen
    ;######################################
    $sFirewallstatus = _ServiceStatus("MpsSvc")
    IniWrite($sInisave, "Service", "firewall", $sFirewallstatus)
    ;######################################
    ;DOS Programm
    ;######################################
    Func _getDOSOutput($command)
    Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2 + 4)
    While 1
    $text &= StdoutRead($Pid, False, False)
    If @error Then ExitLoop
    Sleep(10)
    WEnd
    Return $text
    EndFunc ;==>_getDOSOutput

    [/autoit]

    VIelleicht hat ja jemand von euch eine Idee.

  • Wenn du sagst das funktioniert mal und mal nicht (--> nach dem kompilieren), dann poste vielleicht mal deine ganzen compile-settings. Sagst du "Add required *.au3"? Wenn einige deiner Kollegen die UDF haben und andere nicht könnte das ein Fehler sein.

    $sBackuppath ist dazu vorher nicht deklariert, was auch zu einem Fehler führen könnte.

    Der Fehlermeldung nach denke ich, dass eine Variable nicht von Anfang an als Array deklariert ist und irgend eine Funktion damit ein problem hat.

    Kann mir das leider nicht genauer anschauen da ich die _NTServices.au3 nicht habe aber grad auch keine Zeit um mir da was raus zu suchen ^^

    So Far

    Grüße Yaerox

    Grüne Hölle

    • Offizieller Beitrag
    [autoit]

    _FileReadToArray($sSysteminfo, $aFile)

    [/autoit]


    Du musst zum Einen $aFile vorab deklarieren und zum Anderen (hier entsteht vermutlich der Fehler) prüfen, ob auch tatsächlich nach _FileReadToArray ein Array existiert (kannst den @error der Funktion auswerten). Die Datei existiert entweder nicht, oder du kannst (aus welchen Gründen auch immer - Rechte etc.) nicht darauf zugreifen. Deshalb schlagen die Dateioperationen vermutlich schon fehl. Prüfe doch schon das Schreiben (If FileWrite Then..) auf Erfolg. Jeden Schritt absichern, dann fällt auch die Fehlersuche leichter.

    Achja: Ich kann dir mit 100% Sicherheit sagen, dass die Array.au3 keine Aktien an dem Problem hat (Schon aus dem Grund, da sie hier gar nicht angewendet wird, sondern die File.au3). :P

  • BugFix : Deklariert hat er das Array bzw. vielmehr die Platzhaltervariable (Zeile 23)

    Ansonsten wie Bugfix sagte, du kannst nicht davon ausgehen, dass die Datei auf jedem System existiert und die Berechtigungen ausreichen um diese zu lesen, daher muss grundsätzlich ein Fehler von _fielreadtoarray() abgefangen werden.
    Ergänzend dazu bist du beim nachfolgenden stringsplit() genauso unvorsichtig, was vielleicht sogar eher der Fehler auf diesen Systemen ist. Du gehst grundsätzlich davon aus, dass jede Zeile ein ":" enthält und splittbar ist, sollte das nicht der Fall sein ist das Ergebnisarray nur bis Index 1 ansprechbar (kompletter ungeteilter String), du sprichst später aber einen Index 2 des Arrays an, also auch hier musst du prüfen ob stringsplit erfolgreich war.

    Weitere Anmerkung: Hast du im unteren Abschnitt Code entfernt? Wozu die innere Schleife, wenn sie keinen code enthält?

    Hier mal eine Fassung die dir etwas Feedback gibt, sofern du den Scriptablauf nicht interaktiv verfolgen kannst solltest du statt msgboxen ein Logfile schreiben und ggf. per email versenden

    [autoit]


    if _FileReadToArray($sSysteminfo, $aFile) = 0 then
    exit msgbox(0,"fehler","datei konnte nicht gelesen werden! --> Errorcode: " & @error) ; Programmende, da Datei nicht zugreifbar...

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

    else

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

    For $i = 2 To 33
    $split = StringSplit($aFile[$i], ': ', 1)
    if $split[0] < 2 then
    msgbox(0,"fehler", $aFile[$i] & " konnte nicht gesplittet werden!")
    continueloop ; überspringt diesen Fehlerhaften Dateieintrag
    endif
    For $j = 1 To UBound($split) -1 ; ?????????????????????? hier passiert nix...
    Next
    $split[2] = StringStripWS($split[2], 1)
    IniWrite($sInisave, "Systeminfo", $split[1], $split[2])
    Next

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

    endif

    [/autoit]
  • Hallo Zusammen,

    wahnsinn so viele Antworten hatte ich gar nicht erwartet. Danke schonmal. Ja, das mit der Schleife habe ich vergessen rauszunehmen. Und ganz ehrlich hab ich vor lauter Bäumen den Wald nicht mehr gesehen. Danke für die Tips, ich werde sie demnächst ein- und mein Script umbauen. Was mir auf die schnelle aufgefallen ist das ich das Textfile an einen Ort speichere wo nicht jeder Zugriff hat (das passiert wenn ein Admin dem anderen nichts sagt...)

    Theoretisch sollte es doch auch möglich sein den Inhalt der Variablen $re in ein Array entsprechend einzulesen ohne über ein File zu gehen, oder? (Ich bin noch nicht allzulange bei Autoit, verzeiht mir "n00b-Fragen")


    Gruss

    AyKay

  • Da ich das gerade selbst benötige habe ich mal schnell ne eigene Funktion gebastelt... 8)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    $aResult = _GetSystemInfo()
    _ArrayDisplay($aResult)

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

    Func _GetSystemInfo()
    Local $iPid = Run(@ComSpec & ' /c systeminfo /FO CSV', @ScriptDir, @SW_HIDE, 2 + 4), $sOutput = "", $aData
    Do
    Sleep(20)
    $sOutput &= StdoutRead($iPid, False, False)
    Until @error
    $aData = StringSplit($sOutput, @LF)
    If $aData[0] <> 3 Then Return SetError(1)
    $aName = StringRegExp($aData[1], '\"([^\"]*)\"\,', 3)
    $aValue = StringRegExp($aData[2], '\"([^\"]*)\"\,', 3)
    If UBound($aName) <> UBound($aValue) Then Return SetError(2)
    Local $aReturn[UBound($aName)][2]
    For $i = 0 To UBound($aName)-1
    $aReturn[$i][0] = $aName[$i]
    $aReturn[$i][1] = $aValue[$i]
    Next
    Return $aReturn
    EndFunc ;==>_GetSystemInfo

    [/autoit]

    LG
    Christoph :)

  • Echt super Leute. Danke für die Vielen Tips und Hilfen. Das Programm tut jetzt auf jedem Recher was es soll. Einziges Problem ist noch wenn ich das ganze über die Verteilungssoftware verteile legt er die Ini-Files nicht an. Aber das wird ein Problem mit der Software sein und nicht mit dem Script.


    Grüsse

    AyKay

  • Behalte vll. mal Schreibrechte im Hinterkopf. hatte bei einem Skript in einer anderen Sprache nun das Problem das ich auf dem Netzlaufwerk etwas erstellen wollte aber keine Rechte hatte ;)

    Grüße Yaerox

    Grüne Hölle