Hi Peter !
Denkbar ist vieles .
Hast Du ein konkretes Beispiel das man mal testen könnte, oder ist die Frage rein hypothetisch ?
Hi Peter !
Denkbar ist vieles .
Hast Du ein konkretes Beispiel das man mal testen könnte, oder ist die Frage rein hypothetisch ?
Herzlich Willkommen im Forum .
Nach deiner Beschreibung dürfte AutoIt genau die richtige Programmiersprache sein. Einfach zu lernen aber mit viel Luft nach oben.
Das Backslash wird automatisch hinzugefügt (If StringRight($sSourceFolder, 1) <> "\" Then $sSourceFolder &= "\"), wenn es nicht mit übergeben wurde.
OT : dafür bietet sich auch die Funktion _WinAPI_PathAddBackslash an
Fügt einen Backslash am Ende eines Strings hinzu, um die korrekte Syntax für einen Pfad zu erstellen
$sFilePath | Der Pfad, an den der Backslash angehängt wird. Wenn dieser Pfad bereits einen nachgestellten Backslash aufweist, wird kein Backslash hinzugefügt. |
Aus reiner Neugier : Geht es Dir lediglich darum, einige MB hier und da einzusparen ?
Dort kann man sich dann ggf. auch gleich noch die Veränderungen in den Variablen anschauen ... Z.Zt. behelfe ich mich mit MsgBoxen ...
Eine kleine Tipphilfe zu MsgBoxen und ConsoleWrites :
Nehme folgendes Trivialskript :
Setze den Mauscursor auf die Variable $iCount in der Schleife.
Verwende nun die Tastenkombination ALT-D (natürlich ohne das - Zeichen).
Damit wird automatisch eine ConsoleWrite-Anweisung eingefügt.
Mit der Tastenkombination CTRL-SHIFT-D wird analog eine MsgBox eingefügt.
Mit der Tastenkombination CTRL-ALT-Z können alle so eingefügten Zeilen wieder entfernt werden.
(Zitat von Mars): "Weil die "kompilierte" Datei im Prinzip eine Kombination aus "Interpreter + Skript" ist."
- kann ich nicht so recht nachvollziehen.
Demnach müßte eine dementsprechende exe-Datei immer größer als die Interpreter-Datei "AutoIt3.exe" sein.Dem ist aber nicht so! -
Aus meinen ersten Versuchen mit AutoIt habe ich hier einen "Test Inputbox" - da ist die exe 296kB groß, bei einem Skript von 4kB und dem verwendeten AutoIt3.exe von 715kB (3.3.4.0). Das ist doch schon merkwürdig ...
Wie Mars bereits richtig schrieb, enthält ein 'kompiliertes AutoIt-Skript' (.exe) folgende Komponenten :
- den AutoIt-Interpreter (also die AutoIt3.exe - bzw. AutoIt3_x64.exe falls #AutoIt3Wrapper_UseX64 = Y)
- das Skript sowie verwendete #includes in einer 'tokenized' Variante (a3x)
- Dateien, die mittels FileInstall eingebunden werden
Der Grund, warum Deine kompilierte .exe-Datei kleiner ist als der Interpreter selbst liegt daran, dass die UPX-Komprimierung aktiv ist :
#AutoIt3Wrapper_UseUpx= ;(Y/N) Compress output program. Default=Y
Diese Komprimierung ist aber leider auch ein Hauptgrund für 'false positive' Warnungen von Virenscannern.
Daher wird in diversen Beiträgen empfohlen, sie zu deaktivieren, mittels :
#AutoIt3Wrapper_UseUpx=N
Kann ich herausfinden, wie viele Einträge vorhanden sind?
Dafür verwendet man z.B. die Aggregatfunktion COUNT
Ein gutes Tutorial, siehe : https://www.sqlitetutorial.net/sqlite-count-function/
Für Ausnahmen ist der NOT IN Operator gut geeignet :
Jetzt ist mein Projekt fertig. http://www.rholtz-office.de/counters/getfile.php?id=914
Glückwunsch zur Fertigstellung Deines Projektes .
Sollten bei euch Fehlermeldungen angezeigt werden, dann bitte hier reinschreiben.
Vorschlag :
Poste den Quellcode doch bitte auch hier im Thread. Dann kann sich jede(r) Interessierte die .exe-Datei(en) selbst kompilieren, ohne sie erst von Deine Website herunterladen zu müssen.
wenn ich Dein Skript unkompiliert laufen lasse, bekomme ich folgenden Fehler: ...
Du meinst sicher das Script, dass mumpel in seinem Beitrag #1 gepostet hat, oder ?
Bei meiner bereinigten Variante aus Beitrag #6 kommt es zu keinem Fehler.
Ich suche eine Möglichkeit, einen Base32 (für 2FA) zu erstellen. Ich habe auch etwas gefunden (https://www.autoitscript.com/forum/topic/59…2-encode-decode). Nur wirft die Exe einen Fehler aus ("Eine Variable ist nicht deklariert").
Benötigst Du wirklich eine CUI und .exe mit Übergabe von Kommandozeilenparametern usw. ?
Falls Du 'nur' Base32_Encode und Base32_Decode innerhalb deines Skriptes benötigst, dann langt es völlig aus, die UDF base32.au3 zu inkludieren (siehe Anhang). Ich habe darin lediglich einen Fehler bereinigt.
Beispielskript base32example.au3 - siehe Anhang (die UDF base32.au3 im SkriptDir ablegen) :
Hier noch mal das Beispielskript als Code :
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 6 -w 7
#include <base32.au3>
Global $g_sString, $g_sDecoded, $g_sEncoded
; Beispiel 1 :
$g_sString = "AutoIt3"
$g_sEncoded = _Base32_Encode($g_sString)
$g_sDecoded = _Base32_Decode($g_sEncoded)
MsgBox(0, "Base32 - Beispiel 1 : ", _
"String = " & $g_sString & @CRLF & @CRLF & _
"Encoded = " & $g_sEncoded & @CRLF & _
"Decoded = " & $g_sDecoded & @CRLF)
; Beispiel 2 :
$g_sString = "2FA"
$g_sEncoded = _Base32_Encode($g_sString)
$g_sDecoded = _Base32_Decode($g_sEncoded)
MsgBox(0, "Base32 - Beispiel 2 : ", _
"String = " & $g_sString & @CRLF & @CRLF & _
"Encoded = " & $g_sEncoded & @CRLF & _
"Decoded = " & $g_sDecoded & @CRLF)
Alles anzeigen
Wenn du eine Variable in mehreren Funktionen verwenden möchtest, ohne sie als Parameter zu übergeben, musst du sie als globale Variable deklarieren.
Das bedeutet, dass du die Variable außerhalb aller Funktionen deklarieren und dann mit dem Schlüsselwort "Global" kennzeichnen musst. Dadurch wird die Variable für alle Funktionen im Skript zugänglich.
Nur eine kleine Anmerkung :
Genau genommen liegt jede außerhalb von Funktionen deklarierte Variable im globalen Gültigkeitsbereich (Scope), selbst wenn das Schlüsselwort Local verwendet wird.
Umgekehrt sollte man Deklarationen mittels Global innerhalb von Funktionen aber tunlichst vermeiden.
Ich setze bei globalen Variablennamen, wie häufig empfohlen, das Präfix g_ , also z.B. :
Global $g_VarName
Das hat zwar keinen funktionalen Einfluss, erleichtert einem aber die Zuordnung.
Wenn jetzt aber "GUICtrlSetData($input1[3], IniRead($ini, "3","Sekunden", 2)) ;ggf. den Defaultwert (2) (wenn die Ini nicht gefunden/gelesen werden kann) ändern" darin steht, trägt er die 2 ein so wie es im Code steht aber in der ini steht was anderes und die Zahlen trägt er nicht in die Input Felder.
Hier ein kleines Demoprogramm für eine baugleiche .ini-Datei :
#include <Array.au3>
Global $aInput[4]
Global Const $sIniFile = @ScriptDir & '\timer.ini' ; <=== hier den Namen deiner .ini-Datei einsetzen
If Not FileExists($sIniFile) Then
Exit MsgBox(BitOR(4096, 16), "", "Fehler beim Lesen von : " & $sIniFile & @CRLF)
EndIf
; .ini Werte lesen :
$aInput[0] = 3
$aInput[1] = IniRead($sIniFile, "Timer","Stunden" , 0)
$aInput[2] = IniRead($sIniFile, "Timer","Minuten" , 0)
$aInput[3] = IniRead($sIniFile, "Timer","Sekunden" ,0)
_ArrayDisplay($aInput, $sIniFile)
Alles anzeigen
timer.ini (nur zum Test - die Endung .ini ist als Dateianhang leider nicht zulässig) :
1. Was kommt heraus, wenn Du deine .ini-Datei verwendest ?
2. Prüfe mal die Codierung deiner .ini-Datei :
Sollte diese z.B. als UTF-8 mit BOM codiert sein, dann wird der erste Eintrag (hier der [Sektionsname]) und damit alle zugehörigen key=value Einträge überlesen.
Ja, es muss eine Exe sein, die auch ohne installiertes AutoIt laufen muss. Das ist ja der Sinn der Übung.
Nur zur Info :
Auf dem jeweiligen Zielrechner muss keine AutoIt-Installation vorhanden sein, um .a3x oder auch .au3 Skripte zu starten. Es reicht völlig aus, den (stand-alone) Interpreter (AutoIt3.exe bzw. AutoIt3_x64.exe) aus deinem AutoIt3 Verzeichnis mitzuliefern.
Danke! Wenn ich richtig verstehe, wird dadurch "Compress output program" auf false gesetzt. Aber was bewirkt das? Funktioniert die Exe dann auch noch auf Systemen ohen installiertes AutoIt?
Die Compilerdirektive #AutoIt3Wrapper_UseUpx = N schaltet lediglich die UPX Komprimierung ab.
Virenscanner 'mögen' nach diesem Verfahren komprimierte Programme offenbar nicht besonders und reagieren entsprechend . Details siehe : https://de.wikipedia.org/wiki/UPX
Auf die Lauffähigkeit einer .exe hat das keinen Einfluss - die Datei wird lediglich (etwas) größer.
Sofern keine umfangreichen Dateien (z..B. mittels Base64 oder FileInstall) eingebunden werden, spielt das kaum eine Rolle.
Weitere Möglichkeiten um auf 'false positives' zu reagieren wären :
Manche AV-Programme geben für die Exe-Datei eine Trojaner-Meldung aus. Z.B. der Windows-Defender. Ist das schon jemanden aufgefallen, hat noch jemand eine solche Meldung bekommen?
Sogenannte 'false positives' sind ein seit Äonen lästiges und viel diskutiertes Thema !
Um dieser Problematik (weitgehend) aus dem Wege zu gehen, liefere ich Programme ausschließlich im Format .a3x aus, und starte sie über eine .cmd bzw. Verknüpfung.
Den AutoIt-Interpreter (also : AutoIt3.exe bzw. AutoIt3_x64.exe) darf man, lizenzrechtlich auch für kommerzielle Programme, mit verteilen.
Im englischsprachigen Forum gibt es dazu einen Thread, der seit 2006 läuft. Ich verweise mal auf einen Beitrag, den ich dort geschrieben habe : false positives
Falls Du unbedingt eine .exe ausliefern möchtest, dann sind offenbar folgende Einstellungen von Vorteil :
#AutoIt3Wrapper_UseX64 = Y
#AutoIt3Wrapper_UseUpx = N
Gruß, Musashi
Falls Du einen sogenannten "Countdown Timer" suchst, dann probiere mal dies :
; Quelle : https://www.autoitscript.com/forum/topic/127667-how-to-create-a-countdown-timer-in-autoit/#elControls_885650_menu
; - leicht modifiziert
#include <WindowsConstants.au3>
HotKeySet("{ESC}", _Terminate)
HotKeySet("{F7}", _StartCountdown)
Global $SS_CENTER, $_CountStartVal = 60000, $_Minutes, $_Seconds, $b_Running = False, $bInit = False
$_GuiCountDown = GUICreate ( "CountDown...", 400, 150, @DesktopWidth/2 -200, @DesktopHeight/2 -75, $WS_EX_TOPMOST )
GUISetBkColor (0xA6CAF0)
$TimeLabel = GUICtrlCreateLabel ( "F7=Start", 30, 10, 380, 100, $SS_CENTER )
GUICtrlSetFont ( -1, 50, 400 )
GUISetState ( )
WinSetOnTop ( $_GuiCountDown, "", 1 )
While 1
If Not $bInit Then $TimeTicks = TimerInit ( )
If $b_Running Then
$bInit = True
_Check ( )
EndIf
Sleep (200)
WEnd
Func _Check ( )
$_CountStartVal -= TimerDiff ( $TimeTicks )
$TimeTicks = TimerInit ( )
Local $_MinCalc = Int ( $_CountStartVal / ( 60 * 1000 ) ), $_SecCalc = $_CountStartVal - ( $_MinCalc * 60 * 1000 )
$_SecCalc = Int ( $_SecCalc / 1000 )
If $_MinCalc <= 0 And $_SecCalc <= 0 Then
GUISetBkColor ( 0xFF0000, $_GuiCountDown )
GUICtrlSetData ( $TimeLabel, "Bye !" )
Sleep ( 1000 )
; If @Compiled Then Shutdown ( 13 )
Exit
Else
If $_MinCalc <> $_Minutes Or $_SecCalc <> $_Seconds Then
$_Minutes = $_MinCalc
$_Seconds = $_SecCalc
GUICtrlSetData ( $TimeLabel, StringFormat ( "%02u" & ":" & "%02u", $_Minutes, $_Seconds ) )
If $_Minutes = 0 And $_Seconds <= 10 Then
Beep ( 1200, 100 )
GUISetBkColor ( 0xA093FF, $_GuiCountDown )
EndIf
EndIf
EndIf
EndFunc ;==> _Check ( )
Func _StartCountdown()
$b_Running = True
EndFunc ;==>_StartCountdown
Func _Terminate()
Exit 0
EndFunc ;==>Terminate
Alles anzeigen
... vielleicht hat jemand einen guten Tip.
Hier das Beispiel von Alina mit zugehöriger UDF .
Eine interessante Diskussion zu dem Thema findest Du unter :
Beispielskript :
#include "TxTtoPDF.au3"
#include <File.au3>
Global $sF = FileOpenDialog("Choose a text file", @ScriptDir & "\", "Text file (*.au3;*.txt;*.ini;*cfg)", 1)
If @error Then
MsgBox(4096, "", "No File(s) chosen")
Else
;set the properties for the pdf
_SetTitle("Txt2PDF")
_SetSubject("Convert text file to pdf")
_SetKeywords("pdf, AutoIt")
_OpenAfter(True);open after generation
_SetUnit($PDF_UNIT_CM)
_SetPaperSize("A4")
_SetZoomMode($PDF_ZOOM_CUSTOM, 90)
_SetOrientation($PDF_ORIENTATION_PORTRAIT)
_SetLayoutMode($PDF_LAYOUT_CONTINOUS)
;initialize the pdf
_InitPDF(@ScriptDir & "\Txt2Pdf.pdf")
_LoadFontTT("F1", $PDF_FONT_CALIBRI,$PDF_FONT_ITALIC)
_Txt2PDF($sF, "F1")
;write the buffer to disk
_ClosePDFFile()
EndIf
; #FUNCTION# ====================================================================================================================
; Name ..........: _Txt2PDF
; Description ...: Convert a text file to pdf
; Syntax ........: _Txt2PDF( $sText , $sFontAlias )
; Parameters ....: $sText - file path.
; $sFontAlias - font alias.
; Return values .: None
; Author(s) .....: Mihai Iancu (taietel at yahoo dot com)
; Modified ......:
; Remarks .......: If the string is very long, it will be scaled to paper width
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _Txt2PDF($sFile, $sFontAlias)
Local $hFile = FileOpen($sFile)
Local $sText = FileRead($hFile)
FileClose($hFile)
Local $iUnit = Ceiling(_GetUnit())
Local $iX = 2
Local $iY = Ceiling(_GetPageHeight() / _GetUnit()) - 1.5
Local $iPagina = Ceiling(_GetPageWidth() / $iUnit) - $iX
Local $iWidth = Ceiling($iPagina - $iX);, 1)
Local $lScale
Local $iRanduri = StringSplit($sText & @CRLF & @CRLF & @CRLF & @CRLF, @CRLF, 3)
Local $iHR = 0.5 * Ceiling($iY / (10 * $iUnit))
Local $iPages = Ceiling((UBound($iRanduri)) * $iHR / $iY)
Local $iNrRanduri = Ceiling(UBound($iRanduri) / $iPages-2)
Local $nrp
For $j = 0 To $iPages + 2
$nrp = _BeginPage()
_DrawText(_GetPageWidth()/_GetUnit()-1, 1, $nrp, "F1", 10, $PDF_ALIGN_CENTER)
For $i = 0 To $iNrRanduri - 1
Local $sLength = Round(_GetTextLength($iRanduri[$i + $j * $iNrRanduri], $sFontAlias, 10))
Local $iH = $iY - $iHR * ($i + 1)
Select
Case $iH < 1
_EndPage()
Case $i + $j * $iNrRanduri = UBound($iRanduri) - 1
_EndPage()
Return
Case $sLength > $iWidth - 1
$lScale = Ceiling($iWidth * 100 / $sLength)
_SetTextHorizontalScaling($lScale)
_DrawText($iX, $iH, $iRanduri[$i + $j * $iNrRanduri], $sFontAlias, 10, $PDF_ALIGN_LEFT, 0)
_SetTextHorizontalScaling(100)
Case Else
_DrawText($iX, $iH, $iRanduri[$i + $j * $iNrRanduri], $sFontAlias, 10, $PDF_ALIGN_LEFT, 0)
EndSelect
Next
_EndPage()
Next
EndFunc ;==>_Txt2PDF
Alles anzeigen
Die UDF (TxTtoPDF.au3) findest Du im Anhang (bitte in das SkriptDir des Beispiels kopieren).
Wie im o.a. Thread bereits beschrieben, funktioniert die UDF aber nur für recht einfache Texte (soll keine Kritik sein). Siehe : SumNumbers.txt zu TxT2Pdf.pdf umgewandelt
EDIT :
Das von chesstiger genannte Tool wkhtmltopdf wäre sicher auch einen Blick wert
Wenn GUICtrlRead($LadeImmer) = $GUI_CHECKED ist, dann schreibst Du den Wert 1 in die Sektion [001] der .ini und löscht die Sektion [002].
Andernfalls (also $GUI_UNCHECKED) schreibst Du den Wert 2 in die Sektion [002] der .ini und löscht die Sektion [001].
Bei If IniRead ... fragst Du aber nur die Sektion [001] ab. Diese wurde in Fall von $GUI_UNCHECKEDaber gelöscht. Es greift also die Vorbesetzung 1 und liefert immer CHECKED.
EDIT WhiteHorse :
Zudem liefert If IniRead($ini, "001","HarkenOn/Off Von Laden Immer", "1") Then ... immer TRUE, egal ob beim Value= "1" oder "2" steht.
In beiden Fällen ist der String besetzt, und nur das wird hier geprüft.
Warum verwendest Du überhaupt zwei Sektionen ([001] und [002]) ? Eine würde doch völlig ausreichen.
P.S. : Haken , nicht Harken
Probiere mal das folgende Skript (gemäß den Tipps von BugFix ) :
#include <AutoItConstants.au3>
Local $PID, $sOutput
; 1.
$iPID = Run("netsh interface ipv4 show config", "", @SW_HIDE, BitOR($STDOUT_CHILD, $STDERR_CHILD))
If Not @error Then
ProcessWaitClose($iPID)
$sOutput = StdoutRead($iPID)
EndIf
ConsoleWrite("=====> Output netsh = " & $sOutput & @CRLF & @CRLF)
; 2.
$iPID = Run("ipconfig /all", "", @SW_HIDE, BitOR($STDOUT_CHILD, $STDERR_CHILD))
If Not @error Then
ProcessWaitClose($iPID)
$sOutput = StdoutRead($iPID)
EndIf
ConsoleWrite("=====> Output ipconfig = " & $sOutput & @CRLF)
Alles anzeigen
Hier der dazugehörige Code nachdem ich es mit AuStripper compiliert habe.
Das kann nicht der komplette Code sein, und würde so auch nicht unter Win10 laufen.
Abgesehen von anderen Dingen fehlen z.B. Includes, wie z.B. #include <GuiIPAddress.au3>.