Probleme mit MustDeclareVars

  • Hallöchen alle ihr jungs und mädchen ;)

    vielleicht kann mir jmd helfen:
    Idee Live MultiLanguage Sprachumschaltung
    kleines Extra damit nicht irgendwer an den Sprachen rumfummelt.. encryptchen.

    es ist eigenlich noch nichts ganz fertig darum verzeit mir.. umständliche codingwege ..

    Jz das eigenliche Problem: (FEHLER auf grund von Opt("MustDeclareVars", 1) => bei 0 ist alles okay..)

    Spoiler anzeigen


    "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\ICH\Desktop\AutoIt v3 Script (neu) (2).au3" /UserParams
    +>10:38:22 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0 Keyboard:00000407 OS:WIN_81/ CPU:X64 OS:X64 Environment(Language:0407)
    +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\ICH\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\ICH\AppData\Local\AutoIt v3\SciTE
    >Running AU3Check (3.3.12.0) from:C:\Program Files (x86)\AutoIt3 input:C:\Users\ICH\Desktop\AutoIt v3 Script (neu) (2).au3
    +>10:38:23 AU3Check ended.rc:0
    >Running:(3.3.12.0):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\ICH\Desktop\AutoIt v3 Script (neu) (2).au3"
    --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
    "C:\Users\ICH\Desktop\AutoIt v3 Script (neu) (2).au3" (276) : ==> Variable used without being declared.:
    Func _INIREAD($s_PATH = Default, $f_UseEncryptedINI = Default)
    ^ ERROR
    ->10:38:24 AutoIt3.exe ended.rc:1
    +>10:38:24 AutoIt3Wrapper Finished.
    >Exit code: 1 Time: 1.943

    der Aufruf :

    Spoiler anzeigen
    [autoit]


    #Region - GUI Create
    Local $gui, $1, $2, $3, $4, $5, $6
    $gui = GUICreate('')
    GUISetState()
    $1 = GUICtrlCreateButton("text1", 0, 0, 150)
    ;__AddToMultiLanguage($1, "hahaha")
    $2 = GUICtrlCreateButton("text2", 0, 50, 150)
    ;__AddToMultiLanguage($2)
    $3 = GUICtrlCreateButton("text3", 0, 100, 150)
    ;__AddToMultiLanguage($3)
    $4 = GUICtrlCreateButton("text4", 0, 150, 150)
    ;__AddToMultiLanguage($4)
    $5 = GUICtrlCreateButton("text5", 0, 200, 150)
    ;__AddToMultiLanguage($5)
    $6 = GUICtrlCreateButton("text6", 0, 250, 150)
    ;__AddToMultiLanguage($6)

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

    #EndRegion - GUI Create

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

    #Region - GUI SwitchLoop
    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_Close
    Exit
    Case $1
    Case $2
    Case $3
    Case $4
    Case $5
    Case $6
    $a = _INIREAD(Default)
    ConsoleWrite($a & @CRLF)
    _ArrayDisplay($a, "ENCRIPT")
    Case Else
    EndSwitch
    WEnd
    #EndRegion - GUI SwitchLoop

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

    Die Function

    Spoiler anzeigen
    [autoit]


    Func _INIREAD($s_PATH = Default, $f_UseEncryptedINI = Default)

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

    Local $a_Return[1][2] = [["SECTION", "ARRAYofITEMS"]]
    Local $a_Sections[1] = ["$a_Sections"]

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

    If $s_PATH == Default Then $s_PATH = $__MLUDF_s_ML_FILEPATH & $__MLUDF_s_ML_FILENAME
    If $f_UseEncryptedINI == Default Then $f_UseEncryptedINI = True

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

    If $f_UseEncryptedINI Then
    If $__MLUDF_m_USE_PASSWORD == Default Then $__MLUDF_m_USE_PASSWORD = @ScriptName
    If $__MLUDF_v_USE_ENCRYPT_ALG == Default Then $__MLUDF_v_USE_ENCRYPT_ALG = $CALG_AES_256

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

    Local $s_SpawnFile = _TempFile(Default, Default, ".bin", 9)

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

    If _Crypt_DecryptFile($s_PATH, $s_SpawnFile, $__MLUDF_m_USE_PASSWORD, $__MLUDF_v_USE_ENCRYPT_ALG) Then
    MsgBox($MB_SYSTEMMODAL, "Success", "Operation succeeded.")
    Else
    Switch @error
    Case 1
    MsgBox($MB_SYSTEMMODAL, "Error", "Failed to create the key.")
    Return False ; REPORT
    Case 2
    MsgBox($MB_SYSTEMMODAL, "Error", "Couldn't open the source file.")
    Return False ; REPORT
    Case 3
    MsgBox($MB_SYSTEMMODAL, "Error", "Couldn't open the destination file.")
    Return False ; REPORT
    Case 4 Or 5
    MsgBox($MB_SYSTEMMODAL, "Error", "Decryption error.")
    Return False ; REPORT
    EndSwitch
    EndIf

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

    FileSetAttrib($s_SpawnFile, "+SHOT") ; could help to hide a bit more
    $s_PATH = $s_SpawnFile

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

    EndIf

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

    Local $hFileOpen = FileOpen($s_PATH, $FO_READ)
    Local $lines = _FileCountLines($s_PATH)

    If $hFileOpen = -1 Then Return SetError(1, 0, 0) ; REPORT
    If $lines = 0 And @error Then Return SetError(1, 0, 0) ; REPORT

    For $i = 0 To $lines
    Local $s_FRL = FileReadLine($hFileOpen, $i)
    If StringLeft($s_FRL, 1) == "[" And StringRight($s_FRL, 1) == "]" Then _ArrayAdd($a_Sections, $s_FRL)
    Next

    FileClose($hFileOpen)

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

    $hFileOpen = Null ; Leak Fix

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

    $a_Sections[0] = UBound($a_Sections) - 1

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

    For $i = 1 To $a_Sections[0]
    Local $a_tmp[1][2] = [[StringTrimRight(StringTrimLeft($a_Sections[$i], 1), 1), IniReadSection($s_PATH, StringTrimRight(StringTrimLeft($a_Sections[$i], 1), 1))]]
    _ArrayAdd($a_Return, $a_tmp)
    Next

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

    If $f_UseEncryptedINI Then
    FileDelete($s_SpawnFile) ; delete TempSpawn
    EndIf

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

    Return $a_Return

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

    EndFunc ;==>_INIREAD

    [/autoit]


    Vielen dank Ich hoffe ich hab jetzt auf die schnelle nicht allzuviel vergessen bzw fehler gemacht :thumbup::thumbup:
    :)
    ElCoón ;)

    Einmal editiert, zuletzt von elcojon (5. September 2014 um 13:39)

  • hi,

    ich hab mal das ganze zusammen gefügt und wenn ich den Local so

    [autoit]


    Local $gui, $1, $2, $3, $4, $5, $6, $__MLUDF_s_ML_FILENAME, $__MLUDF_s_ML_FILEPATH, $__MLUDF_m_USE_PASSWORD, $__MLUDF_v_USE_ENCRYPT_ALG

    [/autoit]


    bearbeitet hab ging es, ich hab halt dann unten rausbekommen: Decryption error in deiner MsgBox aber das Script funktioniert..:) lol:D

  • Ich bin mir nicht so sicher, ob das sinnvoll ist einfach alle Variablen global zu deklarieren, wenn er denn schon MustDeclareVars benutzt...
    Hast du schon überprüft, ob irgendeine Variable in deiner Funktion, zum Zeitpunkt des Aufrufens, noch nicht deklariert ist? Möglicherweise ist das einfach nur eine seltsame Zeilenangabe von Au3Check

  • * nur die Variablen $___MLUDF_* sind Global bzw Global Statics ... und alle vars im und um die gui sind nur zum test gedacht..

    Ich hab das gefühl dass es in dem funktionsheader liegt... thoretischw erden alle enthaltenen Variablen/Parameter Lokal für diese einzige Funktion deklariert.
    [[ _INIREAD($s_PATH = Default, $f_UseEncryptedINI = Default) ]] aber scheind als würde das must decar nicht reichen ://

    Ich bin mir nicht so sicher, ob das sinnvoll ist einfach alle Variablen global zu deklarieren, wenn er denn schon MustDeclareVars benutzt...
    Hast du schon überprüft, ob irgendeine Variable in deiner Funktion, zum Zeitpunkt des Aufrufens, noch nicht deklariert ist? Möglicherweise ist das einfach nur eine seltsame Zeilenangabe von Au3Check

    Ja generell schon...

    btw der kopf (Steht da so nix beautified o.ä.):

    Spoiler anzeigen
    [autoit]

    #include-once
    #include <Crypt.au3>
    #include <Array.au3> ;#DEBUG
    ;~ #include <File.au3> ;#DEBUG
    Opt("MustDeclareVars", 1)

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

    Global Static $__MLUDF_f_USE_ENCRYPT_LngFile = True
    Global Static $__MLUDF_m_USE_PASSWORD = Default ; May enter your own pw (Default=@ScriptName)
    Global Static $__MLUDF_v_USE_ENCRYPT_ALG = Default ;Default = $CALG_AES_256
    Global Static $__MLUDF_s_ML_FILEPATH = @ScriptDir & ""
    Global Static $__MLUDF_s_ML_FILENAME = StringTrimRight(@ScriptName, 4) & ".lng"
    ;~ Global Static $__MLUDF_s_ML_FILEHASH = Default ; For more Secure create a hash and put it in...

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

    Global $__MLUDF_a_Languages[1][3] = [["Nr", "ID", "Name"]]
    Global $__MLUDF_a_MLControlTable[1][3] = [["C_Handle", "C_Name", "L_ID"]]

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

    ;~ Global $__MLUDF_a_INI=_INIREAD($__MLUDF_s_ML_FILEPATH&$__MLUDF_s_ML_FILENAME) ;TEST2
    Global $__MLUDF_a_INI = $__MLUDF_s_ML_FILEPATH & $__MLUDF_s_ML_FILENAME
    ;~ Global $__MLUDF_a_INI = _INIREAD(@ScriptDir & "\LNG.TXT") ;TEST

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

    #include <GUIConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    ;~ _INIREAD()

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

    #Region - GUI Create
    Local $gui, $1, $2, $3, $4, $5, $6
    $gui = GUICreate('')
    GUISetState()
    $1 = GUICtrlCreateButton("text1", 0, 0, 150)
    __AddToMultiLanguage($1, "hahaha")
    $2 = GUICtrlCreateButton("text2", 0, 50, 150)
    __AddToMultiLanguage($2)
    $3 = GUICtrlCreateButton("text3", 0, 100, 150)
    __AddToMultiLanguage($3)
    $4 = GUICtrlCreateButton("text4", 0, 150, 150)
    __AddToMultiLanguage($4)
    $5 = GUICtrlCreateButton("text5", 0, 200, 150)
    __AddToMultiLanguage($5)
    $6 = GUICtrlCreateButton("text6", 0, 250, 150)
    __AddToMultiLanguage($6)

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

    ;~ _ArrayDisplay($__MLUDF_a_INI)
    #EndRegion - GUI Create

    [/autoit]

    2 Mal editiert, zuletzt von elcojon (5. September 2014 um 12:05)

  • Das sollte eigentlich nicht passieren. Die Funktionsdeklaration sollte nicht als Aufruf einer Variable gewertet werden, sondern als Deklaration eine lokalen Variable.
    Das Problem liegt auch gar nicht bei Au3Check, die Fehlermeldung kommt von AutoIt. Ich hab so ein Verhalten bis jetzt nur im Zusammenhang mit DllCallbacks beobachtet. ^^.

  • Das sollte eigentlich nicht passieren. Die Funktionsdeklaration sollte nicht als Aufruf einer Variable gewertet werden, sondern als Deklaration eine lokalen Variable.


    also das ist mir jz ehrlichgesagt nich neu :P aber trotzdem gehn mir so langsam die ideen aus.. ;(

  • Ehrlich gesagt komme ich hier nicht mit, weil nie ein vollständiges Minimalbeispiel vorliegt bei dem man mal das Problem direkt nachvollziehen kann.

    Dennoch werfe ich mal einen Suchbegriff für die AutoIt-Hilfe in den Raum:

    [autoit]

    #forceref

    [/autoit]
  • OMG!! :party: okay en kolege hats gepackt ^^ schmerzhafter fail... Es ligt dem ganzen wohl ein Fehler in der Struktur der Au3Check, bzw. was sich auch immer um den check des mustdeclar kümmert, vor.

    $a war weiter oben in einem anderes Case bereits deklariert.
    in case $6 aber noch nicht... der check läft drüber und sieht ein local $a in der while loop und alles is gut... bin der compiler bzw interpreter selbst dran geht :cursing::cursing:

    Spoiler anzeigen
    [autoit]


    Case $6
    $a = _INIREAD(Default)
    ConsoleWrite($a & @CRLF)
    _ArrayDisplay($a, "ENCRIPT")
    Case Else
    EndSwitch

    [/autoit]

    Lösung ;)

    Spoiler anzeigen
    [autoit]

    Case $6
    Local $a = _INIREAD(Default)
    ConsoleWrite($a & @CRLF)
    _ArrayDisplay($a, "ENCRIPT")
    Case Else
    EndSwitch

    [/autoit]


    Trotzdem ein Dank an alle die sich ein kopf gemacht haben :thumbup:

    gibts iwo so ne art sphotline für autoit? :D das könnte man ja im nächsten rl fixen :whistling:

    And Now.. Rock'n'Roll :rock::love:

    Einmal editiert, zuletzt von elcojon (5. September 2014 um 13:46)

  • Es ligt dem ganzen wohl ein Fehler in der Struktur der Au3Check, bzw. was sich auch immer um das mustdeclar kümmert, vor.

    $a war weiter oben in einem anderes Case bereits deklariert.
    in case $6 aber noch nicht...

    Wenn $a lediglich in einem anderen Case deklariert wird, dann ist das kein Fehler von Au3Check sondern schlicht korrekt.
    Mit MustDeclareVars soll sichergestellt werden, dass Variablen erst nach einer expliziten Deklaration initialisiert werden dürfen.
    Wenn die Deklaration aber in einem Case steht ist die Deklaration in einem anderen Case nicht sichergestellt (weil das Case mit der Deklaration unter Umständen nie aufgerufen wird).
    Die Deklaration muss also außerhalb des Switchs passieren wenn eine Variable Case-Übergreifende verwendet wird. Oder in jedem Case wo sie verwendet wird einzeln.

    Für Fälle in denen die Struktur wirklich mal zu komplex für Au3Check ist, nimmt man hingegen #forceref.

    ... und wegen minimal beispiel... wenn ICH code... kann es keiner lesen und jz den ganzen code aufräumen nur um iwas kleines zu fixen.. nää

    Tja dann ist die Wahrscheinlichkeit, dass dir jemand (wie hier) dabei helfen kann und möchte schlicht deutlich geringer.

  • Wenn $a lediglich in einem anderen Case deklariert wird, dann ist das kein Fehler von Au3Check sondern schlicht korrekt.
    Mit MustDeclareVars soll sichergestellt werden, dass Variablen erst nach einer expliziten Deklaration initialisiert werden dürfen.
    Wenn die Deklaration aber in einem Case steht ist die Deklaration in einem anderen Case nicht sichergestellt (weil das Case mit der Deklaration unter Umständen nie aufgerufen wird).
    Die Deklaration muss also außerhalb des Switchs passieren wenn eine Variable Case-Übergreifende verwendet wird. Oder in jedem Case wo sie verwendet wird einzeln.

    Für Fälle in denen die Struktur wirklich mal zu komplex für Au3Check ist, nimmt man hingegen #forceref.


    stimmt fast... bestimme ich eine lokale in einer func. und code unter ihr weiter meckert mustdecare check auch rum... und sie ist theoretisch definiert... jedoch (praktisch) nicht zwingend (mustdecalre) ...

  • Spoiler anzeigen
    [autoit]

    Opt("MustDeclareVars", 1)

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

    Func _EineFunktion()
    Local $Answer=MsgBox (6,0,1)
    EndFunc

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

    $Answer="Hi"
    MsgBox (0,0,$Answer)

    [/autoit]


    // Ich code UNTER _EineFunktion() weiter und es wird mit EndFunc der lokale gültikeits bereich verlassen :huh: // und erkannt...

  • Hier liegen gleich zwei Missverständnisse zu Grunde:

    • Die Deklaration und Definition einer Funktion bedeutet nicht die Ausführung dieser Funktion. Wenn man eine Funktion definiert wird Sie lediglich dem Interpreter namentlich bekannt gemacht und angegeben wo sie steht. Alles was in ihr ausgeführt werden soll wird schlicht erst einmal ignoriert. Erst wenn die Funktion explizit aufgerufen wird, kommt der Code in Ihr zur Ausführung. In AutoIt ist es sogar egal wo die Funktion deklariert wird. Ob vor oder nach einem Aufruf ist egal.
    • Local in einer Funktion bedeutet, dass die damit deklarierte Variable nur innerhalb der Funktion existiert und sichtbar ist. Außerhalb dieser Funktion ist die damit deklarierte Variable nicht sichtbar.


    Aus diesen beiden Gründen ist die Fehlermeldung von Au3Check also vollkommen korrekt.
    Du weist in Zeile 7 einer Variablen namens $Answer einen Wert zu welche in diesem Rahmen nie deklariert wurde.

  • Ich glaube du verstehst da etwas falsch elcojon. Das es einen Fehler gibt ist korrekt!

    Du hast die Variable nur innerhalb der Funktion deklariert, also kennt er diese nach einem EndFunc nicht mehr.

    #Edit: War scheinbar zu langsam für den AspirinJunkie :P

    Grüße Yaerox

    Grüne Hölle

  • zu 1. ja okay hab ich nich ausprobiert aber in c ist das ja so...
    zu 2. ja und genau das gleiche ist bei switch.. switch entscheidet welche "innere Funktion" aufgerufen wird (via wahrheitswert der mittels den cases festgelegt wird) bei select würde ich es ja noch verstehen weil dort mehrere zutreffen können und sie nacheinander abgearbeitet werden aber bei switch? naja.. problem ist jz auf jedenfall bekannt und man weiß jz woran man ist :rolleyes:

  • In C ist das so? Das will ich gerne sehen 8| Ich würde behaupte das ist in C nicht so, da ist alles noch viel strenger ... ich kann mich nicht daran errinnern, dass das in C so sei. Wenn du da ein Beispiel hast darfst du mir das gerne mal zeigen bitte.

    Und verstehe ich dein 2. Punkt korrekt: Du sagst, dass Switch mit Variablen Funktioniert wie eine Funktion, sprich was du dort nutzt, sei danach nicht mehr deklariert?
    Wenn ja, lass dir gesagt sein das ist auch falsch. Bei einem Switch muss die Variable bereits deklariert sein, und somit erübrigt sich der Rest ...

    Grüße Yaerox

    Grüne Hölle

  • In C ist das so? Das will ich gerne sehen 8| Ich würde behaupte das ist in C nicht so, da ist alles noch viel strenger ... ich kann mich nicht daran errinnern, dass das in C so sei. Wenn du da ein Beispiel hast darfst du mir das gerne mal zeigen bitte.


    ... dass man immer UNTER einer function weiter coden muss wenn von dort der aufruf erfolgr ?(

    und zu dem switch.. nein.. aber ohne den davor aufgerufenen case ist das ganze nicht viel mehr... außerdem waren da """""""" ^^

  • zu 1. ja okay hab ich nich ausprobiert aber in c ist das ja so...

    C verhält sich da genauso wie AutoIt auch.
    Folgendes kompiliert in C nicht (Fehlermeldung undeclared identifier müsste kommen):

    Spoiler anzeigen

    zu 2. ja und genau das gleiche ist bei switch.. switch entscheidet welche "innere Funktion" aufgerufen wird (via wahrheitswert der mittels den cases festgelegt wird) bei select würde ich es ja noch verstehen weil dort mehrere zutreffen können und sie nacheinander abgearbeitet werden aber bei switch? naja.. problem ist jz auf jedenfall bekannt und man weiß jz woran man ist

    Wenn du etwas innerhalb von einem Case (egal ob in Switch/Select/If-Else-Endif) deklarierst, ist dessen Deklaration für folgende Codeteile nicht mehr gesichert. Es ist vollkommen logisch und korrekt, dass dabei der Fehler der nicht deklarierten Variable kommt.

    Edit: O.k. dein Vergleich mit C bezog sich auf die Lage der Funktionsdeklaration - das ist dort tatsächlich anders.