Skript-Interpreter in AutoIt - System() Funkton

  • Hallo liebe Community,

    ich versuche mich gerade daran einen Skript-Interpreter in AutoIt zu skripten. Das funktioniert mittlerweile und jetzt möchte ich die Funktion "System()" implementieren, wie man sie in C++ aus dem Header "iostream.h" verwenden kann.

    Bei MSDN habe ich nachgelesen, dass die Funktion "Int" als Rückgabetyp hat und das der Parameter der Funktion als Datentyp "const char*" haben muss. Jetzt meine Frage: Wir realisiere ich "const char*" als Parametertyp? In der Hilfe kann ich nur wstr finden und das löst eine unbehandelte Ausnahme aus. Wie soll ich das machen? Ich will nur wissen wie ich den DLL-Call realisieren soll.

    Hier ist mein Interpretercode:

    Spoiler anzeigen
    [autoit]


    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_outfile=interpreter.exe
    #AutoIt3Wrapper_Change2CUI=y
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

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

    #cs ----------------------------------------------------------------------------

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

    Skript Interpreter in AutoIt
    -----------------------------------------------------------------------

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

    Copyright (c) 2010 by Lord383

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

    #ce

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

    ;#include "windows.au3"
    #include "macro.au3"

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

    #include <Array.au3>
    #include <file.au3>
    #include <String.au3>
    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    #Region Konfiguration

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

    ; Parameterdefinitionszeichen
    Global Const $Parameter_Start= "("
    Global Const $Parameter_End = ")"

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

    ; Gilt jetzt nicht nur für Strings
    Global Const $String_Start = "["
    Global Const $String_End = "]"

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

    ; Zeichen das Parameter trennt
    Global Const $Parameter_Sperator = ","

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

    #EndRegion

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

    ; Kommandozeilenparameter auswerten
    If $CmdLine[0] = 1 Then

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

    _Script_Execute($CmdLine[1])

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

    Else

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

    ; Funktioniert nur, wenn das Skript kompiliert ist
    $Eingabe = FileOpenDialog("Skriptdatei öffnen", "", "Skript (*.skript)")
    If @error Then
    Exit
    Else
    Run(@ScriptFullPath & " " & $Eingabe)
    Exit
    EndIf

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

    EndIf

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

    Func _Script_Execute($sScriptFile)

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

    ; Speicherort für die Skriptzeilen
    Dim $sCommands

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

    ; Kleiner Zwischenspeicher
    Dim $Cache
    Dim $Parameters2

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

    Dim $Param1
    Dim $Param2

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

    #cs
    Dim $Param3
    Dim $Param4
    Dim $Param5
    Dim $Param6
    Dim $Param7
    Dim $Param8
    Dim $Param9
    Dim $Param10
    #ce

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

    Local $Token
    Local $Parameters

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

    ; Jede Zeile ins Array einlesen
    If _FileReadToArray($sScriptFile, $sCommands) Then
    For $i = 1 to $sCommands[0] Step 1
    ; Falls die Zeile leer ist
    If Not $sCommands[$i] = "" Then
    ; Zwischenspeicher mit gesplitteter Zeile
    $Cache = StringSplit($sCommands[$i],$Parameter_Start)
    ; Überprüfung ob es überhaupt Parameter gibt
    If $Cache[0] <= 1 Then
    MsgBox(16, "Fehler in Zeile " & $i, "Inkorrekte Parameter-Klammern: " & $Cache[1])
    Else
    ; Der Befehl
    $Token = $Cache[1]
    ; Die Parameter in Komma getrennt
    $Parameters = StringTrimRight($Cache[2], 1)
    ; Der Befehl wird geswitcht
    Switch $Token
    ; ######################################################## MsgBox ########################################################
    Case "MsgBox"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 2 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein String wird als 1. Parameter benötigt in Zeile " & $i)
    Exit
    EndIf
    ; Parameter 2
    $Param2 = _StringBetween($Parameters2[2], $String_Start, $String_End)
    If (UBound($Param2) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein String wird als 1. Parameter benötigt in Zeile " & $i)
    Exit
    Else
    MsgBox(0, _Script_MacroProcessor($Param1[0]), _Script_MacroProcessor($Param2[0]))
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## Beep ########################################################
    Case "Beep"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 2 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein Integer wird als 1. Parameter benötigt in Zeile " & $i)
    Exit
    EndIf
    ; Parameter 2
    $Param2 = _StringBetween($Parameters2[2], $String_Start, $String_End)
    If (UBound($Param2) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein Integer wird als 2. Parameter benötigt in Zeile " & $i)
    Exit
    Else
    Beep(Number(_Script_MacroProcessor($Param1[0])), Number(_Script_MacroProcessor($Param2[0])))
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## ConsoleWrite ##################################################
    Case "ConsoleWrite"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 1 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein String wird als 2. Parameter benötigt in Zeile " & $i)
    Exit
    Else
    ConsoleWrite(_Script_MacroProcessor($Param1[0]))
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## Sleep ########################################################
    Case "Sleep"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 1 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein Integer wird als 1. Parameter benötigt in Zeile " & $i)
    Exit
    Else
    Sleep(Number(_Script_MacroProcessor($Param1[0])))
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## Goto ########################################################
    Case "Goto"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 1 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Es wird in Zeile " & $i & " eine gültige Zeilennummer benötigt um zu springen.")
    Exit
    Else
    If $Param1 > $sCommands[0] Then
    MsgBox(16, "Fehler in Zeile " & $i, "Das Sprungziel liegt außerhalb des Skripts.")
    Exit
    Else
    $i = Number(_Script_MacroProcessor($Param1[0]))
    EndIf
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ################################################## DownloadFile ########################################################
    Case "DownloadFile"
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 2 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein String wird als 1. Parameter benötigt in Zeile " & $i)
    EndIf
    ; Parameter 2
    $Param2 = _StringBetween($Parameters2[2], $String_Start, $String_End)
    If (UBound($Param2) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Ein String wird als 1. Parameter benötigt in Zeile " & $i)
    Exit
    Else
    InetGet(_Script_MacroProcessor($Param1[0]), _Script_MacroProcessor($Param2[0]), 1, 0)
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## System ########################################################
    Case "System"
    ;MsgBox(0, "Zeile " & $i, "MsgBox")
    $Parameters2 = StringSplit($Parameters, $Parameter_Sperator)
    ;_ArrayDisplay($Parameters2)
    If $Parameters2[0] = 1 Then; Anzahl der Parameter die der Befehl braucht
    ; Parameter 1
    $Param1 = _StringBetween($Parameters2[1], $String_Start, $String_End)
    If (UBound($Param1) > 1) Or @error Or ($Param1 = 0) Then
    MsgBox(16, "Fehler in Zeile " & $i, "Es muss ein gültiger Parameter in zeile " & $i & " übergeben werden.")
    Exit
    Else
    _System(_Script_MacroProcessor($Param1[0]))
    EndIf
    Else
    MsgBox(16, "Fehler in Zeile " & $i, "Zu wenig oder zu viele Parameter für '" & $Token & "' in Zeile " & $i)
    Exit
    EndIf
    ; ######################################################## Exit ########################################################
    Case "Exit"
    Exit
    ; ################################################### Unbekannt ########################################################
    Case Else
    MsgBox(16, "Fehler in Zeile " & $i, "Unbekannter Befehl '" & $Token & "' in Zeile " & $i)
    Exit
    EndSwitch
    EndIf
    EndIf
    Next
    Else
    ; Fehler ausgeben, wenn Datei nicht gelesen werden kann
    MsgBox(16, "Fehler", "Die Datei konnte nicht eingelesen werden. Zugriff verweigert.")
    Exit
    EndIf

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

    EndFunc

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

    Func _System(Const $sExpression)

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

    Local $DLL = DllOpen(@SystemDir & "\msvcrt.dll")
    DllCall($DLL, "int", "system", "const char*", $sExpression)

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

    EndFunc

    [/autoit]


    Der Code des macro Converters

    Spoiler anzeigen
    [autoit]


    #cs ----------------------------------------------------------------------------

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

    Makros (macro.au3)

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

    #ce

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

    Func _Script_MacroProcessor($sExpression)

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

    $sExpression = StringReplace($sExpression, "%AppDataCommonDir%", @AppDataCommonDir)
    $sExpression = StringReplace($sExpression, "%AppDataDir%", @AppDataDir)
    $sExpression = StringReplace($sExpression, "%CommonFilesDir%", @CommonFilesDir)
    $sExpression = StringReplace($sExpression, "%ComputerName%", @ComputerName)
    $sExpression = StringReplace($sExpression, "%CPUArch%", @CPUArch)
    $sExpression = StringReplace($sExpression, "%CR%", @CR)
    $sExpression = StringReplace($sExpression, "%CRLF%", @CRLF)
    $sExpression = StringReplace($sExpression, "%DesktopDepth%", @DesktopDepth)
    $sExpression = StringReplace($sExpression, "%DesktopDir%", @DesktopDir)
    $sExpression = StringReplace($sExpression, "%DesktopHeight%", @DesktopHeight)
    $sExpression = StringReplace($sExpression, "%DesktopRefresh%", @DesktopRefresh)
    $sExpression = StringReplace($sExpression, "%DesktopWidth%", @DesktopWidth)
    $sExpression = StringReplace($sExpression, "%DocumentsCommonDir%", @DocumentsCommonDir)
    $sExpression = StringReplace($sExpression, "%FavoritesCommonDir%", @FavoritesCommonDir)
    $sExpression = StringReplace($sExpression, "%HomeDrive%", @HomeDrive)
    $sExpression = StringReplace($sExpression, "%HomePath%", @HomePath)
    $sExpression = StringReplace($sExpression, "%HOUR%", @HOUR)
    $sExpression = StringReplace($sExpression, "%LogonDNSDomain%", @LogonDNSDomain)
    $sExpression = StringReplace($sExpression, "%LogonDomain%", @LogonDomain)
    $sExpression = StringReplace($sExpression, "%LogonServer%", @LogonServer)
    $sExpression = StringReplace($sExpression, "%MDAY%", @MDAY)
    $sExpression = StringReplace($sExpression, "%MIN%", @MIN)
    $sExpression = StringReplace($sExpression, "%MON%", @MON)
    $sExpression = StringReplace($sExpression, "%MSEC%", @MSEC)
    $sExpression = StringReplace($sExpression, "%MyDocumentsDir%", @MyDocumentsDir)
    $sExpression = StringReplace($sExpression, "%OSArch%", @OSArch)
    $sExpression = StringReplace($sExpression, "%OSBuild%", @OSBuild)
    $sExpression = StringReplace($sExpression, "%OSLang%", @OSLang)
    $sExpression = StringReplace($sExpression, "%OSServicePack%", @OSServicePack)
    $sExpression = StringReplace($sExpression, "%OSType%", @OSType)
    $sExpression = StringReplace($sExpression, "%OSVersion%", @OSVersion)
    $sExpression = StringReplace($sExpression, "%ProgramFilesDir%", @ProgramFilesDir)
    $sExpression = StringReplace($sExpression, "%ProgramsCommonDir%", @ProgramsCommonDir)
    $sExpression = StringReplace($sExpression, "%ProgramsDir%", @ProgramsDir)
    $sExpression = StringReplace($sExpression, "%StartMenuCommonDir%", @StartMenuCommonDir)
    $sExpression = StringReplace($sExpression, "%StartupCommonDir%", @StartupCommonDir)
    $sExpression = StringReplace($sExpression, "%SystemDir%", @SystemDir)
    $sExpression = StringReplace($sExpression, "%TempDir%", @TempDir)
    $sExpression = StringReplace($sExpression, "%UserName%", @UserName)
    $sExpression = StringReplace($sExpression, "%UserProfileDir%", @UserProfileDir)
    $sExpression = StringReplace($sExpression, "%WDAY%", @WDAY)
    $sExpression = StringReplace($sExpression, "%WindowsDir", @WindowsDir)
    $sExpression = StringReplace($sExpression, "%WorkingDir%", @WorkingDir)
    $sExpression = StringReplace($sExpression, "%YDAY%", @YDAY)
    $sExpression = StringReplace($sExpression, "%YEAR%", @YEAR)

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

    return $sExpression

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

    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von Lord383 (5. März 2010 um 21:35)

  • Die Idee _RunDOS() zu verwenden hatte ich mir eher als letzten Ausweg gedacht :) . Ich wollte es eigentlich mit einem DLL-Call lösen, denn ich will nicht extra einen cmd.exe Prozess starten.