Problem nur bei kompiliertem Skript - Fehler in den Includes?

  • Wenn ich das folgende Skript in SciTE ausführen lasse, dann funktioniert alles, aber wenn es kompiliert ist, kommt der Fehler:

    in Zeile 703:Variable used without beeing declared

    Kann mir da jemand helfen? Und wie kann ich die CPU-Auslastung des Skripts verringern?

    Skript:

    Spoiler anzeigen
    [autoit]

    #include <process.au3>
    #include <GUIConstants.au3>
    #include <WindowsCOnstants.au3>
    #include <IE.au3>

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

    HotKeySet("{ESC}","_exit")
    Opt("WinTitleMatchMode", 4)
    $taskbar_pos = WinGetPos("classname=Shell_TrayWnd")
    $taskbar_pos = $taskbar_pos[3]
    Opt("WinTitleMatchMode", 1)

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

    Global $pid,$name,$startram,$Proggui

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

    $title = WinGetTitle("")
    $pid = WinGetProcess($title)
    $name = _ProcessGetName($pid)
    If Not $pid Then Exit
    $startram = _GetRam($pid)

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

    $Proggui = GUICreate("", 296, 35, @DesktopWidth - 296, @DesktopHeight- (35 + $taskbar_pos), $WS_POPUP,$WS_EX_TOOLWINDOW)
    WinSetOnTop($Proggui, "", 1)
    GUISetBkColor(0x004F4F)
    $proggie = GUICtrlCreateProgress(100, 5, 296-105, 15)
    $lab = GUICtrlCreateLabel("100%", 5, 5, 80, 16)
    GUICtrlSetColor(-1, 0x00FFFF)
    $kllab = GUICtrlCreateLabel($name & ":" & $startram & "", 5, 20, 275, 17)
    GUICtrlSetColor(-1, 0x00FFFF)

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

    DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Proggui, "int", 500, "long", 0x00040008);slide-in from bottom
    WinSetOnTop($Proggui, "", 1)

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

    $Pr_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $pid)
    DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $Pr_Handle[0])
    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $Pr_Handle[0])

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

    AdlibRegister("_UpdateRam", 550)

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

    ;Main While, damit das Skript nicht beendet wird
    While Sleep(10)
    $CPU = _GetCPUUsage()
    $CPU0 = $CPU[0]
    If $CPU0 = 1 Then $Auslastung = $CPU[1]
    If $CPU0 = 2 Then $Auslastung = ($CPU[1] + $CPU[2]) / 2
    If $CPU0 = 3 Then $Auslastung = ($CPU[1] + $CPU[2] + $CPU[3]) / 3
    If $CPU0 = 4 Then $Auslastung = ($CPU[1] + $CPU[2] + $CPU[3] + $CPU[4]) /
    GUICtrlSetData($proggie, $Auslastung)
    $title = WinGetTitle("")
    $pid = WinGetProcess($title)
    $name = _ProcessGetName($pid)
    $autoit = _ProcessGetName(@AutoItPID)
    ProcessSetPriority($autoit, 0)
    If Not $pid Then
    Exit
    EndIf
    $startram = _GetRam($pid)
    $ram = _GetRam($pid)
    $temp = _ProcessGetPriority($name)
    If $ram >= 0 Then
    ProcessSetPriority($name, 0)
    EndIf
    If $ram >= 10000 Then
    ProcessSetPriority($name, 1)
    EndIf
    If $ram >= 100000 Then
    ProcessSetPriority($name, 2)
    EndIf
    If $ram >= 1000000 Then
    ProcessSetPriority($name, 5)
    EndIf
    GUICtrlSetData($lab, $temp&" Points | CPU:")
    WEnd

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

    ;_exit, beendet das Skript mit einem fade out der GUI
    Func _exit()
    DllCall ( "user32.dll", "int", "AnimateWindow", "hwnd", $Proggui, "int", 500, "long", 0x00090000 );fade-out
    Exit
    EndFunc

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

    ;_UpdateRam, gut sich alle 750ms an wieviel Memoryauslastung der Prozess hat
    Func _UpdateRam()
    If Not ProcessExists($pid) Then
    AdlibUnRegister()
    For $i = 30 To 0 Step - 1
    $set = $i
    If StringLen($set) < 2 Then $set = "0" & $i
    $set = StringLeft($set, 1) & "." & StringRight($set, 1)
    GUICtrlSetData($kllab,$name&" was terminated! Exit in "&$set)
    GUICtrlSetData($lab,$set)
    Sleep(100)
    Next
    _exit()
    EndIf
    $ram = _GetRam($pid)
    GUICtrlSetData($kllab, $name & ":" & $ram & "")
    $prog = (100 * $ram) / $startram
    Return 1
    EndFunc ;==>_UpdateRam

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

    ;_GetRam($iProcPid), gibt die Memoryauslastung der angegebenden PID zurück
    Func _GetRam($iProcPid)
    Local $colItems = "",$Output = ""
    $objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
    $colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Process", "WQL", 0x30)

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

    If IsObj($colItems) Then
    For $objItem In $colItems
    If $objItem.ProcessId = $iProcPid Then Return $objItem.WorkingSetSize / 1024
    Next
    Else
    MsgBox(48, "WMI Output", "No WMI Objects Found for class: " & "Win32_Process")
    Exit
    EndIf
    EndFunc ;==>_GetRam
    Func _GetCPUUsage()
    Local Const $SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = 8
    Local Const $SYSTEM_TIME_INFO = 3
    Local Const $tagS_SPPI = "int64 IdleTime;int64 KernelTime;int64 UserTime;int64 DpcTime;int64 InterruptTime;long InterruptCount"

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

    Local $CpuNum, $IdleOldArr[1],$IdleNewArr[1], $tmpStruct
    Local $timediff = 0, $starttime = 0
    Local $S_SYSTEM_TIME_INFORMATION, $S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
    Local $RetArr[1]

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

    Local $S_SYSTEM_INFO = DllStructCreate("ushort dwOemId;short wProcessorArchitecture;dword dwPageSize;ptr lpMinimumApplicationAddress;" & _
    "ptr lpMaximumApplicationAddress;long_ptr dwActiveProcessorMask;dword dwNumberOfProcessors;dword dwProcessorType;dword dwAllocationGranularity;" & _
    "short wProcessorLevel;short wProcessorRevision")

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

    ;Anzahl der CPUs bestimmen
    $err = DllCall("Kernel32.dll", "none", "GetSystemInfo", "ptr",DllStructGetPtr($S_SYSTEM_INFO))

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

    If @error Or Not IsArray($err) Then ;Fehler beim 1. Dll Aufruf
    Return $RetArr[0] = -1
    Else
    $CpuNum = DllStructGetData($S_SYSTEM_INFO, "dwNumberOfProcessors")
    ReDim $RetArr[$CpuNum+1]
    $RetArr[0] = $CpuNum
    EndIf
    $S_SYSTEM_INFO = 0

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

    While 1
    ;Erstellen der Struktur für die Prozessor Performance
    $S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = DllStructCreate($tagS_SPPI)
    ;Größe Struktur um später vielfache (MultiCore) der Structur lesen zu können
    $StructSize = DllStructGetSize($S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)
    ;Erstellen einer Pufferstruktur
    $S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = DllStructCreate("byte puffer[" & $StructSize * $CpuNum & "]")
    ;Pointer zum wiederfinden
    $pointer = DllStructGetPtr($S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)

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

    $err = DllCall("ntdll.dll", "int", "NtQuerySystemInformation", _
    "int", $SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, _
    "ptr", DllStructGetPtr($S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), _
    "int", DllStructGetSize($S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), _
    "int", 0)

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

    ;Fehler beim 2. Dll Aufruf
    If $err[0] Then
    Return $RetArr[0] = -2
    EndIf

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

    ;Struktur und Dll-Aufruf für Zeitmessung
    Local $S_SYSTEM_TIME_INFORMATION = DllStructCreate("int64;int64;int64;uint;int")
    $err = DllCall("ntdll.dll", "int", "NtQuerySystemInformation", _
    "int", $SYSTEM_TIME_INFO, _
    "ptr", DllStructGetPtr($S_SYSTEM_TIME_INFORMATION), _
    "int", DllStructGetSize($S_SYSTEM_TIME_INFORMATION), _
    "int", 0)

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

    ;Fehler beim 3. Dll Aufruf
    If $err[0] Then
    Return $RetArr[0] = -3
    EndIf

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

    If $starttime = 0 Then ;Startwerte Ermitteln
    ReDim $IdleOldArr[$CpuNum]
    ;Start-Informationen Auslesen
    For $i = 0 to $CpuNum -1
    $tmpStruct = DllStructCreate($tagS_SPPI, $Pointer + $i*$StructSize)
    $IdleOldArr[$i] = DllStructGetData($tmpStruct,"IdleTime")
    Next
    ;Startzeit ermitteln
    $starttime = DllStructGetData($S_SYSTEM_TIME_INFORMATION, 2)
    ;Verzögerung um einen Zeitunterschied sicher zu stellen
    Sleep(500)
    Else
    ReDim $IdleNewArr[$CpuNum]
    ;Neue Informationen auslesen
    For $i = 0 to $CpuNum -1
    $tmpStruct = DllStructCreate($tagS_SPPI, $Pointer + $i*$StructSize)
    $IdleNewArr[$i] = DllStructGetData($tmpStruct,"IdleTime")
    Next

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

    ;Zeitdifferenze in 100 nanosekunden
    $timediff = DllStructGetData($S_SYSTEM_TIME_INFORMATION, 2) - $starttime

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

    ;Auslastung errechnen
    For $i=0 to $CpuNum -1
    $RetArr[$i+1] = Round(100-(($IdleNewArr[$i] - $IdleOldArr[$i]) * 100 / $timediff))
    Next

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

    Return $RetArr
    EndIf

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

    ;Speicher wieder frei geben
    $S_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION = 0
    $S_SYSTEM_TIME_INFORMATION = 0
    $tmpStruct = 0
    WEnd
    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von campweb (27. Dezember 2010 um 14:37)

  • Mit Sleep(10) in der Hauptschleife kannst du die CPU-Auslastung verringern. Guck doc h mal in den Includes in Zeile 703 ob du herausfindest wie die Variable umbenannt oder Deklariert werden muss. Dein Skript scheint ja keine 703 Zeilen zu haben

  • Wenn es kompiliert ist hat es über 30k Zeilen, woher soll ich denn wissen, welche variable sich da mit was beißt.

  • Komisch, bei mir funktioniert es sowohl kompiliert als auch in SciTE (Win 7 64Bit)
    Und um rauszufinden, welche Variable sich in Zeile 703 befindet, einfach die Include Zeilen durch den Inhalt der Includedatei ersetzen.

  • eetze folgende Zeilen an deinen kriptanfang:

    [autoit]

    #AutoIt3Wrapper_Run_Obfuscator=y
    #Obfuscator_Parameters=/striponly

    [/autoit]

    dadurch erhält du neben der Exe ein File FileName.Obfucated.au3 in dem der komplette verwendete Source (inkluive Include) enthalten ist.
    In Zeile 46 ist (zumindest im eingetellten Skript) ein Fehler:

    [autoit]

    If $CPU0 = 4 Then $Auslastung = ($CPU[1] + $CPU[2] + $CPU[3] + $CPU[4]) /

    [/autoit]


    muss

    [autoit]

    If $CPU0 = 4 Then $Auslastung = ($CPU[1] + $CPU[2] + $CPU[3] + $CPU[4]) / 4

    [/autoit]

    heissen.

    Bei mir läuft die EXE ohne Fehlermeldung, Win XP prof SP3

    mfg autoBert

  • Bis auf einen Syntax-Fehler in Zeile 46 (was auch logisch ist - es fehlt die 4) läuft es bei mir auch.
    Mir ist zwar nicht klar was das Skript macht (beim groben überfliegen sah ich nur das an der Prozesspriorität aufgrund der RAM-Auslastung rumgespielt wird (?!?).
    Ansonsten sind mir ein paar Sachen aufgefallen:

    • Includes welche gar nicht benötigt werden
    • Permanent wird vom AutoItSkript selber der Name mit ProcessgetName() (statt @AutoItExe?) ausgelesen und dann mit ProcessSetPriority() die Priorität gesetzt. Warum nicht nur einmal am Anfang?
    • Die _GetRam-Funktion ist vollkommen ineffektiv wenn sie wirklich permanent aufgerufen werden soll. WMI ist sowieso nicht sehr performant aber bei jedem Aufruf das WMI-Objekt neu zu erstellen ist nicht sehr effektiv. Lieber das Objekt per Static definieren. Ansonsten lieber gleich die komplette Funktion durch folgende ersetzen:
    Spoiler anzeigen
    [autoit]

    Func _GetRam($iPID)
    $iPID = ProcessExists($iPID)
    If $iPID = 0 Then Return SetError(1,0,-1)

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

    Local $aStats = ProcessGetStats($iPID)
    Return $aStats[0] / 1024
    EndFunc

    [/autoit]