AmarokStudios

Include Full Directory

1 post in this topic

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

    • TheSaint
      By TheSaint
      I had a need, and so I developed.
      Before I did that though, I did a quick search of the forum, and found a few things, but none seemed to suit what I really wanted ... though to be honest, I did not investigate them deeply or search extensively. In any case, I am not very good at modifying the code of others, nor do I enjoy doing so, so in the end I decided it was best to start from scratch ... re-inventing the wheel perhaps, but a wheel I feel a certain degree of comfort with. I also thought about Maps, but don't know enough.
      _IniString Functions (was Ini_InMem)
      Ini in memory
      Settings INI - Read/Write once to the disk
      INI File Processing Functions
      ... sure to be others.
      As with all my stuff, feel free to use (no guarantees) or modify ... just give me credit where due.
      I always go for the quick & simple approach, as those who know me here, are well aware, so without a doubt, my code could be improved - sped up, RegExp used, etc. So feel free to do that, and convert into a proper UDF, if you want, following best practices etc, as I am sure others will appreciate it.
      Recently, I have come upon a need to extract data from an approximately 50 Mb downloaded Index file, just extracting the few elements I need, and storing them in an INI file. It is quite a time consuming process, especially on my underpowered Netbook, which is where I am using the program I built. I have been considering ways to speed up things. Two good sounding methods, out of several possibles, have come to mind - 1) RAM Disk and 2) Virtual INI processing. That last being a better option, when sharing code (program) with others.
      Another method, which I am currently using, that did give me some measurable benefit, was to download the almost 50 Mb Index file in Stages (i.e. 30 x 1.4 Mb roughly), extracting data from each in turn. I have also considered extracting to 10 (or 11) separate INI files, rather than the single large INI file (4~5 Mb), as things noticeably slow up as the INI file increases in size ... obviously due to writing time.
      I can't really speed up the extraction process, but that last method may speed up the writing stage.  However, it would require significant program changes, and perhaps not gain me much benefit. To complicate things, there are too many Section names (Index ID's) for the IniReadSectionNames command, so I have had to split them off into their own (read/write) line-by-line index file, and create code to deal with duplicates. When read, Index ID's and Titles populate a Listbox control in a user GUI.
      So at this point in time, it seems best to use the Virtual INI approach to gain a significant reduction in time taken. For my own specific use, with my slow Netbook, I may also use a RAM Disk.
      Due to the aforementioned INI issues, and lack of available specific data, probably because it is always  program concentric, I have created an ASCII Checker program, which I guess you can say, is AutoIt  concentric. Because others may also find it handy, I am providing it here. NOTE - As yet, I am only aware that Escape characters exist, but have not investigated or catered for them in any way.
      ASCII Checker.zip

      The Virtual_INI_UDF is still a work in progress, though I have done most of the functions now, with the working but incomplete _Ini_Test function, still requiring changes etc from the information gleaned by the ASCII Checker program.
      Here's something to play with meanwhile.
      Updated files (21st February 2017)
      Virtual_INI_UDF.au3
      Example.au3
      All pretty basic, but managed to load my 4 Mb INI file (seemingly ok, but took a few seconds) ... though I have only worked with much smaller testing ones so far.
      P.S. While I have done a fair amount of testing, it has been pretty basic, and mostly limited to the examples provided. Testing has definitely not been extensive.
    • Valnurat
      By Valnurat
      I hope my title is good enough.
      I'm using the ADO UDF and I have question regarding editing SQL records with this UDF.
      The owner of the UDF suggested an idea, but maybe there is another trix.
    • Valnurat
      By Valnurat
      I have a SQL db. I would like to view the content in a control. Like a table. The control should have the option to show every 2nd line in another color. When you pick a "cell" it should pick the whole row. When you dobbelt click on the row another windows should popup with the content from the row.
      What view control can do that?
    • Valnurat
      By Valnurat
      How do I access a sql database for inserting and reading?
    • Valnurat
      By Valnurat
      I'm trying to get some info from dell.com page. I use a servicetag to find the computer. From the computerinfo I would like to get the "Shipping Date", but the date is on the next "cell".
      I have done this and I don't know if this is correct aproach, but I do get some info out.
      I just don't know how to "jump" to the next cell.
       
      #include <IE.au3> #include <MsgBoxConstants.au3> Local $oIE = _IECreate("http://www.dell.com/support/home/dk/da/dkbsdt1/product-support/servicetag/gnn5f12/configuration") Local $oTds = _IETagNameGetCollection($oIE, "td") Local $sTxt = "" For $oTd In $oTds $sTxt &= $oTd.innertext & @CRLF Next MsgBox($MB_SYSTEMMODAL, "Form Input Type", " Types :" & @CRLF & $sTxt) _IEQuit($oIE) I have seen something like this in VBscript
      Cell.NextSibling.NextSibling.innertext Is there someone who could help me.