Bin unterwegs daher nur Stichworte.
Quick&Dirty: Dateien, Verstexkte GUI auslesen
Komplexer: TCP/IP Kommunikation
Meisterhaft: Memory-Reading, Child-Process
Für was interessierst du dich? ![]()
Bin unterwegs daher nur Stichworte.
Quick&Dirty: Dateien, Verstexkte GUI auslesen
Komplexer: TCP/IP Kommunikation
Meisterhaft: Memory-Reading, Child-Process
Für was interessierst du dich? ![]()
Sehe gerade: Das ist kein "zuverlässiges" Problem: Es tritt mal auf und mal nicht. Es hat nichts mit der eigentlichen Installation zu tun. Es ist wurscht ob es VM oder RM ist. Bei beiden tritt das Problem gleichermaßen auf.
Das einzige, was mir aufgefallen ist, ist, dass das Problem SEHR offensichtlich von Aldi.de verursacht wird. Denn EGAL welche Webseite ich dahinter setze, das Problem tritt weiter auf. Setze ich hingegen eine andere beliebige Seite ein - zum Beispiel autoit.de mit dem Suchwort "autoit" - funktioniert alles fehlerfrei. Das Problem scheint zu sein, dass Aldi niemals den "complete" - Status erreicht, was etwas unglücklich ist.
Das Problem ließe sich grundsätzlich dadurch lösen, dass eben nur eine Seite abgehandelt wird pro Object - an deinem Beispiel oben:
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
;~ #AutoIt3Wrapper_Res_requestedExecutionLevel=highesAvailable
;~ #AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <IE.au3>
_n("http://www.aldi.de/")
_IEReady(0, "http://www.aldi.de/", "USA", 5)
_n("http://www.bing.de/")
_IEReady(0, "http://www.bing.de/", "Bing", 5)
_n("http://www.autoit.de/")
_IEReady(0, "http://www.autoit.de/", "autoit", 5)
Func _IEReady($ier_id, $ier_target, $ier_searchtext, $ier_timeout = 20)
$ier_handler = _IECreate("about:blank", 0, 1, 0, 1)
$temp = WinWait("[CLASS:IEFrame]", "", 30)
ConsoleWrite("> Starting..." & @CRLF)
_IENavigate($ier_handler, $ier_target, 0)
Local $ier_current_runtime = TimerInit()
Local $ier_time_delta = 0
If Not (IsNumber($ier_timeout) == 1) Then
; If the timeout is no number (Integer or Float) set a default value
$ier_timeout = 20
EndIf
;DEV
Local $ie_readystate
Do
$ie_readystate = _IEPropertyGet($ier_handler, "readystate")
$ier_time_delta = TimerDiff($ier_current_runtime)
_p(StringFormat("Timer: %s - Readystate: %s", $ier_time_delta, $ie_readystate))
Until $ie_readystate >= 1 Or ($ier_time_delta >= $ier_timeout * 1000)
;DEV
Local $ier_clipboard = ""
Local $ier_fail = True
Do
$ier_clipboard = ""
; Gets the source code of the website
$ier_clipboard = _IEBodyReadHTML($ier_handler)
; Gets the readystate of the website
$ie_readystate = _IEPropertyGet($ier_handler, "readystate")
$ier_time_delta = TimerDiff($ier_current_runtime)
_p(StringFormat("Timer: %s - Readystate: %s || (Write HTML into Error Log)", $ier_time_delta, $ie_readystate))
_p($ier_clipboard) ;DEV
; Checks if the searchtext is in the source code
If StringInStr($ier_clipboard, $ier_searchtext) <> 0 Then
; Searchtext is in the Source code. Print a measage (MsgBox)
$ier_fail = False
_m($ier_clipboard)
Else
; No match
$ier_fail = True
EndIf
$ier_time_delta = TimerDiff($ier_current_runtime)
Sleep(125) ;DEV
Until ($ier_fail = False) Or ($ier_time_delta >= $ier_timeout * 1000)
If $ier_fail = False Then
; String Found
ConsoleWrite(StringFormat("+ Website Test: String %s found on Website", $ier_searchtext) & @CRLF)
_IEQuit($ier_handler)
Return True
Else
; String not found
ConsoleWrite(StringFormat("! Website Test: could not find string: %s", $ier_searchtext) & @CRLF)
_IEQuit($ier_handler)
Return False
EndIf
EndFunc ;==>_IEReady
Func _p($m)
;ConsoleWrite($m & @CRLF)
EndFunc ;==>_p
Func _m($m)
;MsgBox(0, "", "String Found " & $m)
EndFunc ;==>_m
Func _n($m)
ConsoleWrite("- " & $m & @CRLF)
EndFunc ;==>_n
Alles anzeigen
Das klärt zwar nicht, wo das Problem herkommt, aber es klärt zumindest, wie das Problem gekonnt ignoriert wird.
Leider ist der Pattern aber ziemlich nutzlos, da er auch ungültige IP-Adressen zulässt im Gegensatz zu dem oben - außer dem gekürzten oben und dem im Eigangsposting. Das Kürzen bei IP-Adressen führt bloß dazu das der RegEx wertlos wird. Dann kann man auch gleich (\d+\.\d+\.\d+\.\d+) verwenden. Etwa genauso sinnvoll, da es genauso wenig absichert, dass die Eingabe auch wirklich eine gültige IP ist.
0.0.0.0 ist keine gültige IP. Ebenso 255.255.255.255.
Das Problem tritt auch auf realer Hardware auf - zumindestens mit der aktuellen AutoIt-Version.
Das Problem ist einfach und ein typischer "DAU"-Fehler: Du verwechselt AutoIt mit einer Hochsprache. Dein Fehler im Script lässt sich mit einem Zeichen zu viel erklären: Du verwendest in Zeile 32 "==" um zu prüfen, ob $ier_timeout 1 zurückgibt. Dies ist in AutoIt allerdings nicht zulässig. Glaube in AutoIt steht "==" für "identisch".
"If Not (IsNumber($ier_timeout) = 1) Then" wäre korrekt und führt nicht mehr zu dem oben beschriebenen Problem.
$sOutput = "Irgendwas..."
Dim $aSearch [11] = ["INTERNATIONAL_ECONOMY(4)", "INTERNATIONAL_PRIORITY(1)", "INTERNATIONAL_PRIORITY_FIRST(6)", "EUROPE_FIRST_INTERNATIONAL_PRIORITY(null)", "PRIORITY_OVERNIGHT(1)", "INTERNATIONAL_PRIORITY_DISTRIBUTION(null)", "MON ", "TUE ", "WED ", "THU ", "FRI "]
Dim $aReplace[11] = ["International Economy", "International Priority", "International Priority First", "International Europe First", "Priority Overnight", "International Priority Distribution", " ", " ", " ", " ", " "]
For $i = 0 To UBound($aSearch) - 1
$sOutput = StringReplace($sOutput, $aSearch[$i], $aReplace[$i], 0, 1)
Next
Dein Beispiel von oben mal mit einer Schleife. Besser wäre allerdings die Search / Replacewerte nicht hart zu vercoden (im Quelltext zu halten) sondern extern - zum Beispiel in einer Datei. Dazu gibt es zig Möglichkeiten. Von einer Ein-Datei-Lösung mit Seperator über zwei Dateien in der jede Zeile mit der gleichen Zeile der anderen Datei überschrieben wird bis hin zu kompletten Übersetzungstabellen - letzteres wird zum Beispiel oft bei mehrsprachigen Produkten verwendet, um die Übersetzung geschmeidig zurecht zu biegen.
Wenn du zu einem dieser Lösungen eine Frage hast, werde ich dir das gerne noch erläutern.
Ja, Kanas Array reicht von [0][0] bis [33][1]... ![]()
Damit ist sowohl [34][0] und [34][1] außerhalb der Reichweite. Schön, dass du dein Problem lösen konntest. ![]()
Ich habe die Funktion tatsächlich einfach umgedreht...
In das Array wird reingeschrieben, wenn es eben NICHT auf das RegEx passt. Bedeutet: Gleiches RegEx für beide.
#include <Array.au3>
#include <Crypt.au3>
$sPfad = @ScriptDir & "\" & "Crypt"
Global $sUserKey = "AutoIt crypted mir auch rekursiv die Dateien!"
_EncryptFolder($sPfad)
_EncryptFolder($sPfad)
_DecryptFolder($sPfad)
_DecryptFolder($sPfad)
_EncryptFolder($sPfad)
_DecryptFolder($sPfad)
_EncryptFolder($sPfad)
_DecryptFolder($sPfad)
_DecryptFolder($sPfad)
_DecryptFolder($sPfad)
_DecryptFolder($sPfad)
_EncryptFolder($sPfad)
_DecryptFolder($sPfad)
Func _EncryptFolder($sFolder)
$aDateien = _RecursiveFileListToArray_Negative($sFolder, '\.crypt', 1)
For $i = 1 To $aDateien[0]
If $aDateien[$i] <> "" Then
_Crypt_EncryptFile($aDateien[$i], $aDateien[$i] & ".crypt", $sUserKey, $CALG_AES_256)
FileDelete($aDateien[$i])
EndIf
Next
EndFunc
Func _DecryptFolder($sFolder)
$aDateien = _RecursiveFileListToArray($sFolder, '\.crypt', 1)
For $i = 1 To $aDateien[0]
If $aDateien[$i] <> "" Then
_Crypt_DecryptFile($aDateien[$i], StringReplace($aDateien[$i], ".crypt", "", 1), $sUserKey, $CALG_AES_256)
FileDelete($aDateien[$i])
EndIf
Next
EndFunc
Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
Local $hSearch, $sFile, $sReturn = ''
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*.*')
If @error Or $hSearch = -1 Then Return SetError(0, 0, $sReturn)
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
$sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
ContinueLoop
EndIf
If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFunc
Func _RecursiveFileListToArray_Negative($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
Local $hSearch, $sFile, $sReturn = ''
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*.*')
If @error Or $hSearch = -1 Then Return SetError(0, 0, $sReturn)
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
If Not StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
$sReturn &= _RecursiveFileListToArray_Negative($sPath & $sFile & '\', $sPattern, $iFlag, 0)
ContinueLoop
EndIf
If Not StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFunc
Alles anzeigen
Vorteil bei dieser Methodik:
Wenn du die Funktion "_EncryptFolder" aufrufst, werden nur die verschlüsselt, die noch nicht verschlüsselt sind - und umgekehrt. Das bedeutet, dass es nicht nur Nutzerfreundlicher wird, sondern dass es auch scheiß egal ist, wie du drum rum programmierst. In jedem Fall funktioniert das verschlüsseln / entschlüsseln. Theoretisch müsstest du nicht mal prüfen, ob der Schlüssel passt - sonst müsstest du ihn ja speichern, und das wäre Prinzip "Haustürschlüssel von außen in der Haustüre".
Einfach versuchen zu entschlüsseln mit dem Key, den er mitgegeben hat. Wenn es der Falsche war, wird die Datei dann eben noch weiter verschlüsselt. Dann müsste er die Datei *verschlüsseln* mit dem letzten Key, damit die Datei wieder im Ursprungszustand existiert... irgendwie ironisch. x)
@chip: Es macht halt Spaß... ![]()
Wie ich gestern noch schreiben wollte:
"Aus Endnutzer-Sicht hochriskant:
Es besteht die Möglichkeit die Daten mehrfach zu verschlüsseln, weil jemand "die komische Datei da" gelöscht hat, genau wie die Möglichkeit besteht, dass gar nicht mehr entschlüsselt werden kann - aus selben Grund. Die Datei ansich erfüllt also keinen tieferen Zweck als "ist da"."
Ja, du kannst das prüfen. Dazu müsstest du die Funktionen allerdings anpassen - zum entschlüsseln bräuchtest du zum Beispiel den Dateifilter "\.crypt". Für das andere brauchst du entweder einen hochkomplexen RegEx, oder du musst die Funktion einmal komplett umkehren...
#include <Array.au3>
#include <Crypt.au3>
$sPfad = @ScriptDir & "\" & "CryptThis"
Global $sUserKey = "AutoIt crypted mir auch rekursiv die Dateien!"
_DecryptFolder($sPfad)
Func _EncryptFolder($sFolder)
$aDateien = _RecursiveFileListToArray($sFolder, '', 1)
For $i = 1 To $aDateien[0]
_Crypt_EncryptFile($aDateien[$i], $aDateien[$i] & ".crypt", $sUserKey, $CALG_AES_256)
FileDelete($aDateien[$i])
Next
EndFunc
Func _DecryptFolder($sFolder)
$aDateien = _RecursiveFileListToArray($sFolder, '\.crypt', 1)
For $i = 1 To $aDateien[0]
_Crypt_DecryptFile($aDateien[$i], StringReplace($aDateien[$i], ".crypt", ""), $sUserKey, $CALG_AES_256)
FileDelete($aDateien[$i])
Next
EndFunc
Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
Local $hSearch, $sFile, $sReturn = ''
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*.*')
If @error Or $hSearch = -1 Then Return SetError(0, 0, $sReturn)
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
$sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
ContinueLoop
EndIf
If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFunc
Alles anzeigen
Das könnte dir weiter helfen:
Die Crypto-Funktionen findest du in der Crypt.au3
Good luck.
Der "Trick" ist übrigens hier:
"StringInStr(FileGetAttrib($sSourceC & $sObjectC),"D")"
Er guckt, ob die gefundene "Datei" das Flag "D" gesetzt bekommen hat. D = Directory = Ordner
Du lässt nach, Chessi. In deinem letzten "Shoutbox-Zitate" war ja sogar ich - mehrfach - dabei... *fg*
Das ist schön zu hören.
Am besten du setzt den Thread auch gleich auf "erledigt" ![]()
Klingt so, als würdest du versuchen die "OutlookSignature.exe" nachzuschreiben - ein Programm, das es bereits gibt. ![]()
Das einzige Encoding, das AutoIt von Haus aus beherrscht und auch auslesen kann ist das der htm-Datei: UTF-16LE. Die txt-Datei hat das windows-1252 encoding. Und die RTF... standard RTF eben: "A standard RTF file can consist of only 7-bit ASCII characters, but can encode characters beyond ASCII by escape sequences."
@mirko:
Wenn du bereits Ansprüche dieser Art stellst, solltest du _StringProper vermeiden. Die Funktion selbst ist deutlich länger als die oben genannte, die sich bequem auf zwei Zeilen ohne Leistungsverlust stauchen lässt, führt zu exakt dem selben Ziel nur ist dabei *deutlich* langsamer. Hier einige Testmessungen - über 100000 Versuche:
SALZBURG
P: Salzburg 0.0522118798000357
L: Salzburg 0.00635305860000865
FuLdA
P: Fulda 0.0367447256999982
L: Fulda 0.00645217520000883
Frankfurt
P: Frankfurt 0.0589764258999852
L: Frankfurt 0.00650131850000692
....
Ich glaube das Muster dürfte zu erkennen sein. Egal wie man ein einzelnes Wort schreibt: StringLower2 / Gross2 oder wie man die Funktion auch nennen mag ist immer schneller, einfach weil _StringProper nicht für einzelne Worter, sondern für komplette Sätze gemacht wurde, und daher auch einen RegEx verwendet.
CRouch: Beide Probleme treten bei der Label-Lösung nicht auf - just sayin.
Damit du es mit GDI+ abfangen kannst, ob es einen Rahmen hat oder nicht, musst du selbst wissen, wo du nun einen Rahmen gezogen hast, und wo nicht. Hierfür bietet sich zum Beispiel ein Array an...
Dein Problem ist ganz einfach:
Du hast einen OnEvent-Code. Trotzdem wartet das Programm darauf, das das letzte Event abgeschlossen wurde.
Leichter verständlich ist es vielleicht so: Dein Programm hat von dir gesagt bekommen, es soll etwas tun, solange "1 gilt" ist. Also durchgehend. Bis du irgendwas anderes sagst. Soweit klar. Jetzt hast du dem Programm aber auch gesagt, wenn ein Nutzer auf den Button hier drückt, mach mal zwischendrin das hier. Bedeutet: Wenn dein Programm mit dem für "zwischendrin" fertig ist, kommt es zu seiner eigentlichen Aufgabe zurück - der Endlosschleife. Wozu solltest du also eine Endlosschleife in der Endlosschleife benötigen? ![]()
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
Global $gui1
Global $gui2
Global $okbutton1
Global $okbutton2
Opt("GUIOnEventMode", 1) ; Wechsle in den OnEvent Modus
$gui1 = GUICreate("GUI 1", 400, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked", $gui1)
$okbutton1 = GUICtrlCreateButton("OK1", 270, 50, 60)
GUICtrlSetOnEvent($okbutton1, "OKButton1")
GUISetState(@SW_SHOW, $gui1)
While Sleep(1000)
ConsoleWrite("Schleife Außen" & @CRLF)
WEnd
Func zweitegui()
$gui2 = GUICreate("GUI 2", 100, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked", $gui2)
$okbutton2 = GUICtrlCreateButton("OK2", 20, 50, 60)
GUICtrlSetOnEvent($okbutton2, "OKButton2")
GUISetState(@SW_SHOW, $gui2)
EndFunc ;==>zweitegui
Func OKButton1()
MsgBox(0, "GUI Event", "Du hast auf OK1 geklickt!")
zweitegui()
EndFunc ;==>OKButton1
Func OKButton2()
MsgBox(0, "GUI Event", "Du hast auf OK2 geklickt!")
GUISetState(@SW_HIDE, $gui2)
EndFunc ;==>OKButton2
Func CLOSEClicked()
MsgBox(0, "GUI Event", "Du hast auf CLOSE geklickt! Programm wird beendet...")
Exit
EndFunc ;==>CLOSEClicked
Alles anzeigen
Das Prinzip ist einfach:
Schritt 1: Wir schmeißen alle zusätzlichen Leerzeichen raus (hoffe in deiner Datei verwendest du tatsächlich auch Leerzeichen wie oben dargestellt - ansonsten den Part anpassen [Zeile 6-8])
Schritt 2: Nun splitten wir das Array-Element (den String) an dem letzten verbleibenden Leerzeichen. Zeile 9.
Schritt 3: In Zeile 3 habe ich eine fiktive "Quelle" erfunden. Dadurch kann ich in den Zeilen 10 bis 13 den Dateinamen, die Dateigröße, den Pfad zur Datei und was von wo nach wo kopiert werden müsste einzeln ausgeben.
$aFiles = FileReadToArray(@ScriptDir & "\test.txt")
$sQuelle = @ScriptDir & "\"
For $i = 0 To UBound($aFiles) - 1
Do
$aFiles[$i] = StringReplace($aFiles[$i], " ", " ")
Until @extended = 0
$aFile = StringSplit($aFiles[$i], " ", 3)
ConsoleWrite("Dateiname: " & $aFile[0] & @CRLF)
ConsoleWrite("Dateigröße: " & $aFile[1] & @CRLF)
ConsoleWrite("Pfad zur Datei: " & $aFile[2] & @CRLF)
ConsoleWrite("! " & $sQuelle & $aFile[0] & " -> " & $aFile[2] & $aFile[0] & @CRLF)
ConsoleWrite(@CRLF)
Next
Alles anzeigen
Ausgabe:
Dateiname: mt-core.js
Dateigröße: 94425
Pfad zur Datei: P:\Dateien\wamp3\www\s2\
! C:\Users\AutoIt\Desktop\mt-core.js -> P:\Dateien\wamp3\www\s2\mt-core.js
Dateiname: mt-full.js
Dateigröße: 116829
Pfad zur Datei: P:\Dateien\wamp3\www\s2\
! C:\Users\AutoIt\Desktop\mt-full.js -> P:\Dateien\wamp3\www\s2\mt-full.js
Dateiname: mt-more.js
Dateigröße: 28449
Pfad zur Datei: P:\Dateien\wamp3\www\s2\
! C:\Users\AutoIt\Desktop\mt-more.js -> P:\Dateien\wamp3\www\s2\mt-more.js
Die Funktion führt allerdings dazu das ALLE (!) Wortanfänge groß geschrieben werden. Nach deinem Post oben eigentlich nicht dein Ziel.
Siehe:
$sString = "Die Transportkosten für Ihre Sendung von DE-36037 FULDA nach AT-5061 SALZBURG betragen 41.79 EUR"
#Include <String.au3>
$sOut = _StringProper($sString)
_GetCities()
MsgBox(64, "_StringProper", $sOut)
$sTemp = $sString
For $i = 0 To UBound($aCities)-1
$sTemp = StringReplace($sTemp, $aCities[$i], StringLower2($aCities[$i]))
Next
MsgBox(64, "StringLower2", $sTemp)
Func StringLower2($sInput)
Local $sOutput
$sOutput = StringLower($sInput)
Return StringUpper(StringLeft($sOutput, 1)) & StringTrimLeft($sOutput, 1)
EndFunc
Func _GetCities()
$iCount = 2
Global $aCities[$iCount]
$aCities[0] = "Fulda"
$aCities[1] = "Salzburg"
EndFunc
Alles anzeigen
Meine Methode hat eben nur den Nachteil, dass du erst einmal alle benötigten Städte in ein Array bringst.