Jump to content
AmarokStudios

Include Full Directory

Recommended Posts

AmarokStudios

Good afternoon AutoIt community!,

I was on Stackoverflow the other day and came across this question: How To Include Files From A Directory. This got me thinking... There has to be a way to do it... After a bunch of research, I wasn't able to find anything. So, I created this UDF to dynamically include every file from the directory. Of course, there are some bugs that I'd like to fix eventually, but for the most part, it works. Simply call the main function (Shown below) right after the rest of the includes before any of your actual code, and the UDF will include all of the au3 files in the specified directory. Without further ado, here is the _includeDir UDF and how to use it!

 

_includeDir.au3

Spoiler
#cs
        Name: _includeDir.au3
        Developer: Timothy Bomer
        Copyright: Amarok Studios LLC 2016
        Version: 1.0
        Description:
            The purpose of this UDF is to dynamically include all files inside of a folder.
            It works for the most part, but I am still working on a couple of bugs.
#CE


#Include <File.au3>


Global $mainUDF = "IncludeDirUDF"
Global $includeLib = $mainUDF & "\" & "loadIncludes.au3"
Global $tempLib = $mainUDF & "\" & "lib.txt"
Global $includeRewrite = $mainUDF & "\rewrite.au3"
Global $iDirHolder = ""


Func _includeDir($iDir, $lineToInc = 1, $restart = True)
    If (checkInclude()) = 1 Then
        FileDelete($tempLib)
        return
    EndIf
    If NOT (FileExists($iDir)) Then
        MsgBox(16,"Directory Doesn't Exists | _includeDir","The directory " & $iDir & " does not exist!")
        return 0
    EndIf
    $iDirHolder = $iDir
    initializeCheck()
    ; MsgBox(0,"Include Directory", "Attempting to include: " & $iDir)
    populateLib($iDir)
    populateIncLib()
    finalize($lineToInc, $restart)
EndFunc

Func checkInclude()
    FileOpen(@ScriptName, 0)
    For $i = 1 to _FileCountLines(@ScriptName)
        $checkLine = FileReadLine(@ScriptName, $i)
        If ($checkLine = '#Include "IncludeDirUDF\loadIncludes.au3"') Then
        return 1
        EndIf
    Next
EndFunc

; START Initialize Check
Func initializeCheck()
    ; MsgBox(0,"Checking. . .", "Is this initialized?")
    If (FileExists($mainUDF)) Then
        If NOT (FileExists($includeLib)) Then
            isError(2)
            return
        EndIf

        ; MsgBox(0,"Initialized","The UDF has been initialized")
    Else
        isError(1)
        return
    EndIf
EndFunc
; END Initialize Check

; START Library Population
Func populateLib($iDir = $iDirHolder)
    ; MsgBox(0,"Populating","Attempting to populate the library")
    If (FileExists($tempLib)) Then
        ; MsgBox(0,"Temp File Found","The temporary library file has been found. Attempting to populate.")
        $tLibCont = _FileListToArray(@ScriptDir & "\" & $iDir & "\", "*")
        $iDirSize = $tLibCont[0]
        ; MsgBox(0,"Size of Included Directory", $iDir & " contains " & $iDirSize & " files to include!")
        $writeLib = FileOpen($tempLib, 1)
        While $iDirSize > 0
            FileWriteLine($writeLib, '#Include "..\' & $iDir & '\' & $tLibCont[$iDirSize] & '"')
            $iDirSize -= 1
        WEnd
        FileClose($writeLib)
    Else
        isError(3)
        return
    EndIf
EndFunc
; END Library Population

; START Include Library Population
Func populateIncLib()
    ; MsgBox(0,"Rewriting. . .", "Attempting to re-write the include library")
    #CS
    If (FileExists($includeLib)) Then
        FileDelete($includeLib)
        _FileCreate($includeLib)
    EndIf
    #CE
    FileOpen($tempLib, 0)
    For $i = 1 to _FileCountLines($tempLib)
        $line = FileReadLine($tempLib, $i)
        $reWriteLib = FileOpen($includeLib, 9)
        FileWriteLine($reWriteLib, $line)
        FileClose($reWriteLib)
    Next
    FileClose($tempLib)
EndFunc
; END Include Library Population

; START Finalize
Func finalize($lineToInc, $restart)
    _FileWriteToLine(@ScriptName, $lineToInc, '#Include "IncludeDirUDF\loadIncludes.au3"', False)
    If ($restart = True) Then
        runFile(@ScriptName)
    EndIf
    exit
    return
EndFunc


Func runFile($rFile)
    $file_loc = $rFile

    If @Compiled = 1 Then
         $file_exe = FileGetShortName(@AutoItExe & ' /AutoIt3ExecuteScript "' & $file_loc & '"')
         Run($file_exe)
    Else
         $file_au3 = FileGetShortName($file_loc)
         Run(@AutoItExe & " " & $file_au3, "", @SW_HIDE)
     EndIf
EndFunc

; START Error Reporting
Func isError($eFlag = "", $eMessage = "There was an error!")
    If ($eFlag = "") Then
        ; MsgBox(16,"ERROR", $eMessage)
        Exit
    EndIf

    If ($eFlag = 1) Then
        ; MsgBox(16,"Not Initialized","This UDF has not been initialized")
        DirCreate($mainUDF)
        Sleep(250)
        initializeCheck()
        return
    ElseIf ($eFlag = 2) Then
        ; MsgBox(16,"Missing File","Missing the include library!")
        _FileCreate($includeLib)
        initializeCheck()
        return

    ElseIf ($eFlag = 3) Then
        ; MsgBox(16,"Missing File", "Missing the temporary library! Creating it now!",3)
        _FileCreate($tempLib)
        populateLib()
        return
    EndIf
EndFunc
; END Error Reporting

 

 

Download this code (_includeDir.au3 attached as well) and place it into the directory with your current script. Next, include it in your main file. For now, I'm going to be using one called Example.au3.

 

#Include "_includeDir.au3"

Now, include whatever else you're going to be including in this script, then call the _includeDir function. NOTE: THIS MUST BE CALLED AT THE TOP OF THE SCRIPT, BEFORE ANY CODE IS WRITTEN! THE FUNCTION FORCES THE SCRIPT TO RESTART SO PUTTING IT LATER IN THE SCRIPT WILL RE-RUN THE CODE!

 

Example.au3

#Include "_includeDir.au3"
#Include <File.au3> ; Not needed. Just here as an example of a normal script.
#Include <Array.au3> ; Not needed. Just here as example of normal script.
_includeDir("Directory to Include")

MsgBox(0,"Example","This is just an example!")

See how the function is called near the top? This is the proper use of the UDF. If you had a folder called "Directory to Include" and had a bunch of .au3 files inside of it, the function would include them all into the Example.au3 script.

If you run the Example.au3 file now, it will most likely tell you "The directory Things to Include does not exist!". Make sure you enter the name of the directory you're trying to include. Just as a side note, when including files, you should put all of the code in the INCLUDED files inside of functions so they aren't automatically run when included. Variables can be outside of the functions so they are automatically set. Remember, if you have a variable in one included file with the same name of variable in another included file, it will be overwritten with whichever include file was included last.

 

Anyways, if you have pointed the directory to include parameter to a folder that exists and run the Example.au3, it will generate a folder called IncludeDirUDF. It will also write a new line inside of Example.au3. It will write the line 

Quote

#Include "IncludeDirUDF\loadIncludes.au3"

on line one. Of course, you don't always want it to be written to line one, right? Maybe you want this bit of code to be written on line 3 in order to keep your code organize. Is there a way to do this? Absolutely! Simply add the line number as a second parameter to the function. For example, we want to have this bit of code written on line 3, we would set up our Example.au3 file to look like this.

#Include "_includeDir.au3"
#Include <File.au3> ; Not needed. Just here as an example of a normal script.
#Include <Array.au3> ; Not needed. Just here as example of normal script.
_includeDir("Directory to Include", 3)

MsgBox(0,"Example","This is just an example!")

See how we added the 3 to the end of _includeDir? This will tell the function to write the #Include "IncludeDirUDF\loadIncludes.au3" on line 3 of Example.au3. Note, the line HAS TO EXIST in order to be written to it. For example, if your Example.au3 code only has 6 lines, and you specify to be written on line 7, it WILL NOT WORK.

 

The code is designed to include and restart in order to process the included files. For some reason, if you want to JUST generate the included file and NOT restart, you can add one more parameter to the code. If you don't want the code to restart, simply set your code up to look like this:

#Include "_includeDir.au3"
#Include <File.au3> ; Not needed. Just here as an example of a normal script.
#Include <Array.au3> ; Not needed. Just here as example of normal script.
_includeDir("Directory to Include", 3, False)

MsgBox(0,"Example","This is just an example!")

Note, if you set this last parameter to false, it will simply generate the included file and write to line 3 of Example.au3 (As specified before) and exit before the code reaches the MsgBox() and it will not be displayed.

 

The last important thing to note: In order to re-include a different set of files, you must delete the #Include "IncludeDirUDF\loadIncludes.au3" from your main script (In this case, Example.au3) and delete the generated file, IncludeDirUDF. Now you can simply rerun Example.au3 and it will include any the dir with any changes you made to it. Only .au3 files should be in the directory you're trying to include as it will not process the other files and will generate an error.

 

I hope this UDF helps somebody out! Comment any questions/concerns you may have and I will try to address them as soon as possible!

 

Thanks,

Timothy

CEO - Amarok Studios

_includeDir.au3

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • gahhon
      By gahhon
      I only found that AutoIt can actually execute the entire python script or execute the .exe (converted to .exe from .py)
      But what if I just want call the particular function? If that possible to do so?
      This is because python can't create fancy GUI like AutoIT does. So my plan is use AutoIT to have fancy GUI.
      Then each buttons will trigger specific function in the python script or .exe file.
      For instances:
      btnSum - trigger function in python script or .exe file (funcSum)
      btnMinus - trigger function in python script or .exe file (funcMinus)
       
      Thanks for advance information.
    • nacerbaaziz
      By nacerbaaziz
      Hello my friends
      Can we create a single context menu on more than one item?
      For example, a context menu includes standardized options on more than one control, such as buttons or check boxes
      to Create a context menu on one item am using this function
      GUICtrlCreateContextMenu ($ HWND)
      How to link it with more than one element please?
      or if we can't do that, please give me a solution
      so i tried to add an context menus to all the controls but the script will be long, for that if their are any solutions i hope to give it to me
      thanks in advanced
    • kurtykurtyboy
      By kurtykurtyboy
      GuiFlatButton is a UDF to easily create regular buttons with different colors for background, foreground, border, hover, focus, etc..
      This started as an effort to change the background color of a button and eventually grew into a full UDF.
      If you've looked around forums for changing button background colors, you have probably noticed that each proposed workaround has its own set of issues/side-effects. The answers usually circle back to 'use ownerdrawn buttons' and 'not worth it'. Well, now it is possible for anyone to easily create ownerdrawn buttons - totally worth it!
      Some issues with other workarounds such as drawing with GDI+ or using a colored label as a 'button':
      Not 'real' buttons so you lose built-in functionality that windows gives to buttons Messy / inefficient code in the main while loop to check for mouse position Slow to respond to click, paint, etc... Having to deal with GUIRegisterMsg messages Not straight-forward to implement GuiFlatButton is not a workaround; it is a technique to respond to Windows' built-in owner-drawn button events.
      With minimal effort, we can now create true simple colored buttons.
      The idea is to create an owner-drawn button using GUICtrlCreateButton then subclass the GUI and controls to handle the button-specific events to paint it however we want.
      This UDF magically does all of this for us! No need to worry about event handling or main while loop logic.
       
      How to use
      It couldn't be any easier! Simply create a new button using the familiar syntax. This creates an ownerdrawn button with default colors.
      $mybutton1 = GuiFlatButton_Create("Button 1", 78, 20, 120, 40) If you want to change the background and text colors:
      GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) Advanced Usage
      Set background/text/border all at once
      GuiFlatButton_SetColors(-1, 0x0000FF, 0xFFFFFF, 0x9999FF) Set ALL colors for ALL button states! (normal, focus, hover, selected)
      Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetColorsEx(-1, $aColorsEx) Set default colors to apply to any future buttons
      ;set colors GuiFlatButton_SetDefaultColors(0x0000FF, 0xFFFFFF, 0x9999FF) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40) Set ALL color defaults
      ;set colors Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetDefaultColorsEx($aColorsEx) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40)  
      Available Functions
       
      Simple Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;GUI with one button Func Example() Local $hGUI, $mybutton1 $hGUI = GUICreate("GuiFlatButton Ex0", 275, 120) GUISetBkColor(0x333333) $idLabel = GUICtrlCreateLabel("Click the button", 10, 100, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) ;create new button then set the background and foreground colors $mybutton1 = GuiFlatButton_Create("Button 1", 78, 20, 120, 40) GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $mybutton1 $i += 1 GUICtrlSetData($idLabel, $i) ConsoleWrite($i & @CRLF) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example
      Menu/Toolbar Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;Example GUI with toolbar Func Example() Local $hGUI, $idLabel, $aButtons, $iTbSize $hGUI = GUICreate("GuiFlatButton Ex2", 300, 200) GUISetBkColor(0x444444) $idLabel = GUICtrlCreateLabel("Click a button", 10, 180, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) $aButtons = createToolbar() $iTbSize = UBound($aButtons) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aButtons[0] To $aButtons[$iTbSize - 1] ConsoleWrite("1") GUICtrlSetData($idLabel, GuiFlatButton_Read($iMsg)) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example Func createToolbar() Local $aButtons[6] Local $bkColor = 0x777777 Local $textColor = 0xFFFFFF Local $borderColor = 0x999999 Local $aBtnClrs[12] = [0x777777, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x888888, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x999999, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x666666, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT] For $i = 0 To UBound($aButtons) - 1 $aButtons[$i] = GuiFlatButton_Create("B" & $i, $i * 50, 0, 50, 17) GuiFlatButton_SetColorsEx($aButtons[$i], $aBtnClrs) Next Return $aButtons EndFunc ;==>createToolbar
      I'm sure there are some use-cases I've forgotten, so feedback is welcome!

      Update 2019-02-09
      Added 2 new functions to set the button colors globally for all future buttons.
      GuiFlatButton_SetDefaultColors 
      GuiFlatButton_SetDefaultColorsEx
      Download the UDF and several examples: GuiFlatButton.zip

      Credits to:
      Melba23 (UDF template)
      LarsJ (general subclassing code)
      4ggr35510n (TrackMouseEvent example)
      binhnx (disable dragging with $WS_EX_CONTROLPARENT)
      GUIRegisterMsg in AutoIt Help (owner-draw button example)
    • gahhon
      By gahhon
      _Metro_SplashTextScreen(1, "", $iMsg) AdlibRegister("_Metro_LoopInProgress") DirRemove($DIR_WA_FOLDER, 1) Local $iCopy = _WinAPI_ShellFileOperation($CUR_WA_FOLDER, $DIR_WA_FOLDER, $FO_COPY, BitOr($FOF_SIMPLEPROGRESS, $FOF_NOCONFIRMMKDIR)) AdlibUnRegister("_Metro_LoopInProgress") _Metro_SplashTextScree If @error Then _Metro_MsgBox(0, "", $iCopy) _FileWriteLog($LOG_INSTALLATION, "Error: " & $iCopy) Else _Metro_MsgBox(0, "", "Application is up to date!") _FileWriteLog($LOG_INSTALLATION, "Debug: Application is up to date.") EndIf According to the help file of _WinAPI_ShellFileOperation there are a lot of failure and error code. But how can I handle all of them and display corresponding error message based on the help file?
      The incident is like this:
      I'll lock the folder with permission, so when I execute the _WinAPI_ShellFileOperation to copy and overwrite the folder contents, it popped me an error message saying that permission issue to caused I can't access the folder and overwrite the contents.

      Then I clicked Cancel button, and my AutoIT application exit immediately and it's not execute the function _Metro_MsgBox(0, "", $iCopy) to display the message.
       
      Anyway, I did also tried the code below, the it still display "Application is up to date!"
      According to the help file, 120 - Security settings denied access to the source.
      If @error = 120 Then _Metro_MsgBox(0, "", $iCopy) _FileWriteLog($LOG_INSTALLATION, "Error: " & $iCopy) Else _Metro_MsgBox(0, "", "Application is up to date!") _FileWriteLog($LOG_INSTALLATION, "Debug: Application is up to date.") EndIf  
    • gahhon
      By gahhon
      I have a application that have a function is to create a shortcut to desktop, lets say is ChromePortable.lnk.
      $iCreate = FileCreateShortcut($DIR_WA_FOLDER & '\GoogleChromePortable.exe', $DIR_SHORTCUT, $DIR_WA_FOLDER, '--kiosk "https://example.com/"') So the shortcut will be launch as kiosk mode and force to enter the specific website. However, the user is still able to right-click on the shortcut and modify the target value to remove the kiosk mode. What can I do to disable the user to editing the target value?
      So far, I had asked and tried from SuperUser for advises Disable Shortcut Target Field
      icacls "ChromePortable.lnk" /GRANT EVERYONE:RX So this will set the permission of this shortcut file to only Read & Execute only! But after I set it, the user is still can modify.
      Please kindly advise.
      Please note and assume that user don't have Administration account or etc, that should be only have 1 account to logon to the computer.
       
      EDIT:
      I must disable inheritance to remove all others permissions like SYSTEM, ADMINISTRATORS, etc. Then only GRANT everyone for READ & EXECUTE only.
      But still the user can go to edit the permissions tho. Any advise?
×