Au3Optimizer

  • Moin,

    mit diesem Skript kann man seine eigenen Skripte optimieren, soll heißen es werden die Funktionen aus den UDFs extrahiert und in das Quellskript eingefügt, das minimiert die kompilierte exe ein wenig. ;)

    au3Optimizer über's Kontextmenü starten (optional)

    Spoiler anzeigen
    [autoit]


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

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

    AutoIt Version: 3.2.4.9
    Author: Greenhorn

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

    Script Function:
    Registryeinträge für das Kontextmenü. (Optimize Script)

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

    #ce ----------------------------------------------------------------------------

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

    RegWrite("HKLM\SOFTWARE\Classes\AutoIt3Script\Shell\Optimize Script\Command", _ ; Registryeinträge für das Kontextmenü.
    "", "REG_SZ", '"' & @ProgramFilesDir & "\AutoIt3\au3Optimizer.exe" & '" "%1"') ; au3Optimizer muss im AutoIt3 Ordner zu finden sein.
    Exit

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

    ; Delete Shell Command
    ;RegDelete('HKLM\SOFTWARE\Classes\AutoIt3Script\Shell\Optimize Script')

    [/autoit]

    au3Optimizer
    (Enthält zwei UDFs --> Kompilierte Größe: 209.646 KB, unoptimiert: 240.624 KB)

    Spoiler anzeigen
    [autoit]


    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_outfile=D:\Programme\AutoIt3\Au3Optimizer.exe
    #AutoIt3Wrapper_Res_Comment=Includes only the Funktions which are needed to run Script
    #AutoIt3Wrapper_Res_Description=Optimizes your au3 Files
    #AutoIt3Wrapper_Res_Fileversion=0.5.0.1
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #cs ----------------------------------------------------------------------------

    AutoIt Version: 3.2.4.9
    Author: Greenhorn

    Script Function:
    AutoIt Code Minimizer.
    Includes only the Funktions which are needed to run Script.

    #ce ----------------------------------------------------------------------------

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

    If $cmdline[0] <> 0 Then
    Global $ScriptFile = $cmdline[1]
    Else
    Global $ScriptFile = FileOpenDialog('Select Source Script', _
    'c:\Downloads\AutoIt-Skripte\Entwicklung\ForumTests\', '(*.au3)', 0, 'Source.au3')
    EndIf

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

    #region Main
    Global $ArUDF
    Global $StrScriptFile = FileRead(FileOpen($ScriptFile, 0))
    Global $ScriptFunction = _Search_FuncInSource()
    ; Hier würde ich gern @error setzen, funzt aber nicht...
    FileCopy($ScriptFile, StringRegExpReplace($ScriptFile, '.au3', 'Bak.au3'))
    Global $OptScript = FileOpen($ScriptFile, 2)
    FileWrite($OptScript, StringRegExpReplace($StrScriptFile, '(?i)#include[ ]*<[ ]*.*\.au3[ ]*>', ''))
    FileWriteLine($OptScript, '')
    FileWriteLine($OptScript, '#Region User Defiened Funktions')
    _Search_FuncInInclude()
    FileWriteLine($OptScript, '#EndRegion User Defiened Funktions')
    FileClose($OptScript)
    Exit
    #endregion

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

    #region Funktions
    ; Search for _Functions in Source File
    Func _Search_FuncInSource()
    $funcs = StringRegExp($StrScriptFile, '_[a-zA-Z0-9]+(?=[ ]*\()', 3)
    If @error = 1 Then
    MsgBox(64, '', 'Das Skript enthält keine benutzerdefinierten Funktionen')
    Exit
    EndIf
    Return _ArrayUnique($funcs)
    EndFunc ;==>_Search_FuncInSource

    Func _ArrayUnique(ByRef $aArray, $vDelim = '', $iBase = 1, $iUnique = 1)
    If $vDelim = '' Then $vDelim = Chr(01)
    Local $sHold
    For $iCC = $iBase To UBound($aArray) - 1
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iUnique) Then _
    $sHold &= $aArray[$iCC] & $vDelim
    Next
    Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim)
    EndFunc ;==>_ArrayUnique

    ; Search and extract Functions from UDF file
    Func _Search_FuncInInclude()
    $ArFiles = _FileListToArray(@ProgramFilesDir & '\AutoIt3\Include', '*.au3', 1)
    For $i = 1 To $ArFiles[0]
    If StringInStr($StrScriptFile, $ArFiles[$i]) Then
    _FileReadToArray(@ProgramFilesDir & '\AutoIt3\Include\' & $ArFiles[$i], $ArUDF)
    _Extract_Func()
    EndIf
    Next
    EndFunc ;==>_Search_FuncInInclude
    ; Extract Function and writes to file
    Func _Extract_Func()
    For $i = 1 To $ArUDF[0]
    For $int = 0 To UBound($ScriptFunction) - 2
    If StringInStr($ArUDF[$i], 'Func ' & $ScriptFunction[$int]) Then
    Do
    ConsoleWrite($ArUDF[$i] & @CRLF)
    FileWriteLine($OptScript, $ArUDF[$i])
    $i += 1
    Until StringInStr($ArUDF[$i], 'EndFunc') <> 0
    FileWriteLine($OptScript, $ArUDF[$i])
    FileWriteLine($OptScript, '')
    EndIf
    Next
    Next

    EndFunc ;==>_Extract_Func
    #endregion

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

    #Region User Defiened Funktions
    Func _FileCreate($sFilePath)
    ;==============================================
    ; Local Constant/Variable Declaration Section
    ;==============================================
    Local $hOpenFile
    Local $hWriteFile

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

    $hOpenFile = FileOpen($sFilePath, 2)

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

    If $hOpenFile = -1 Then
    SetError(1)
    Return 0
    EndIf

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

    $hWriteFile = FileWrite($hOpenFile, "")

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

    If $hWriteFile = -1 Then
    SetError(2)
    Return 0
    EndIf

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

    FileClose($hOpenFile)
    Return 1
    EndFunc ;==>_FileCreate

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

    Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)
    Local $hSearch, $sFile, $asFileList[1]
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If (StringInStr($sFilter, "\")) Or (StringInStr($sFilter, "/")) Or (StringInStr($sFilter, ":")) Or (StringInStr($sFilter, ">")) Or (StringInStr($sFilter, "<")) Or (StringInStr($sFilter, "|")) Or (StringStripWS($sFilter, 8) = "") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    $hSearch = FileFindFirstFile($sPath & "\" & $sFilter)
    If $hSearch = -1 Then Return SetError(4, 4, "")
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then
    SetError(0)
    ExitLoop
    EndIf
    If $iFlag = 1 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") <> 0 Then ContinueLoop
    If $iFlag = 2 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") = 0 Then ContinueLoop
    ReDim $asFileList[UBound($asFileList) + 1]
    $asFileList[0] = $asFileList[0] + 1
    $asFileList[UBound($asFileList) - 1] = $sFile
    WEnd
    FileClose($hSearch)
    Return $asFileList
    EndFunc ;==>_FileListToArray

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

    Func _FileReadToArray($sFilePath, ByRef $aArray)
    ;==============================================
    ; Local Constant/Variable Declaration Section
    ;==============================================
    Local $hFile

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

    $hFile = FileOpen($sFilePath, 0)

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

    If $hFile = -1 Then
    SetError(1)
    Return 0
    EndIf

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

    $aArray = StringSplit(StringStripCR(FileRead($hFile, FileGetSize($sFilePath))), @LF)

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

    FileClose($hFile)
    Return 1
    EndFunc ;==>_FileReadToArray

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

    #EndRegion User Defiened Funktions

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

    Jetzt müsste ich den Code im Hauptskript etwas übersichtlicher gestalten und überflüssige Leerzeilen entfernen, ist irgendwie 'n ganz schönes Kuddelmuddel...

    Gruß
    Greenhorn


    • Offizieller Beitrag
  • Danke für den Link, Bernd. =)

    Das habe ich schon geahnt, dass es so etwas schon gibt, jedoch wollte ich es trotzdem mit AutoIt versuchen, in kleinem Rahmen... ;)


    Gruß
    Greenhorn