Warning: Many of these scripts require additional files which will be included in the download.
Executing these scripts without those files could result in anything from minor irritations to code failure.
Be sure to download the zip file if you plan on using the code.

   Filex.au3

Last modified:   Wednesday, September 30, 2020

;*******************************************************************************
;
;   Function List
;         __File_RemoveEmptyLines()
;         __FileReadToArray()
;         __FileWriteFromArray()
;         _File_Compare()
;         _File_CompareDate()
;         _File_Compare_MD5()
;         _File_CompareVersion()
;         _File_CountLines()
;         _File_CountLines2()
;         _File_Ext_PropertiesGet()
;         _File_GetDate()
;         _File_GetOwner()
;         _File_MoveByDate()
;         _File_ReadFromLine()
;         _File_SetOwner()
;
;*******************************************************************************

#Include-once
Global $_MD5CodeBuffer
;===============================================================================
; Function Name:   __File_Read2Array()
; Description:     Another version of __FileReadToArray() which will also
;                   accept string blocks
; Syntax:          __File_Read2Array("File path | string block")
; Parameter(s):    $sStr = File path or text block to read to the array
; Requirement(s):
; Return Value(s): 0 based array
; Author(s):   George (GEOSoft) Gedye, Smoke_N
; Modification(s):
; Note(s):    This can also be used to read the clipboard or any string to an array
; Example(s):   $aArray = __File_Read2Array("c:\windows\setuplog.txt")
;               $aArray = __File_Read2Array(ClipGet())
;===============================================================================

Func __File_Read2Array($sStr)
    If FileExists($sStr) Then $sStr = FileRead($sStr)
    $avArray = StringRegExp($sStr, "(?s)(.+?)(?m:$|\r\n)|(.+?)(?m:$|\r)|(.+?)(?m:$|\n)", 3)
    If NOT IsArray($avArray) Then Return SetError(1, 0, 0)
    Return $avArray
EndFunc   ;==>__File_Read2Array

;===============================================================================
; Function Name:    __File_RemoveEmptyLines()
; Description:      Removes Blank lines from a file
; Syntax:           __File_RemoveEmptyLines($sFile[,starting point[, All|double ]])
; Parameter(s):     $sFile - Full path and filename of the file
;                   $iStart - line to start stripping empty lines -default is first line
;                   $all - 0 (default) remove only extra consecutive blank lines
;                        - 1 Remove all blank lines
; Requirements:      None
; Return Value(s):  On Success - Returns the corrected file
;                   On Failure - Sets @Error to
;                                      - 1 if unable to create the array
;                                      - 2 file write operation failed
; Author(s):        George (GEOSoft) Gedye
; Modifications:    Added $all to remove all or extra blanks
;                   Added $iStart - position to start removing empty lines
; Note(s):
;===============================================================================

Func __File_RemoveEmptyLines($sFile, $iStart = 1, $All = 0)
    Local $aArray = __FileReadToArray($sFile), $I, $sOut = "", $hFile, $fo
    If NOT IsArray($aArray) Then Return SetError(1)
    If $iStart > 1 Then
        FOR $I = 1 To $iStart
            $sOut &= $aArray[$I] & @CRLF
        Next
    EndIf
    FOR $I = $iStart To UBound($aArray) - 1
        If $All <> 0 Then
            If StringStripWS($aArray[$I], 8) = "" Then ContinueLoop
        Else
            If StringStripWS($aArray[$I], 8) = "" AND StringStripWS($aArray[$I - 1], 8) = "" Then _
                    ContinueLoop
        EndIf
        $sOut &= $aArray[$I] & @CRLF
    Next
    FileCopy($sFile, $sFile & ".bak", 1);; for safety
    $hFile = FileOpen($sFile, 2)
    $fo = FileWrite($hFile, StringStripWS($sOut, 2))
    FileClose($hFile)
    If $fo = 0 Then ;; Something went wrong so restore the file
        FileCopy($sFile & ".bak", $sFile, 1)
        SetError(2)
    EndIf
    FileDelete($sFile & ".bak")
EndFunc   ;==>__File_RemoveEmptyLines

;===============================================================================
; Function Name:    __FileReadToArray()
; Description:      Reads a text file and returns an array where each element contains a line of text
; Syntax:           _FileReadToArray($sFilePath)
; Parameter(s):     $sFilePath - Path and filename of the file to be read
; Requirements:      None
; Return Value(s):  On Success - Returns an array of the text file
;                   On Failure - Sets @Error to 1 and returns 0
; Author(s):        Jonathan Bennett [jon at hiddensoft dot com]
; Modifications:    GEOSoft 08/01/07 - Removed the $aArray Parameter so it doesnt need to be pre-declared
;                                       Now just call it with $myArray = _FileReadToArray($File)
;                           05/15/08 - Now will split on @CR if @LF not found, as in many html pages.
; Note(s):          None
;===============================================================================

Func __FileReadToArray($sFilePath)
    Local $hFile
    $hFile = FileOpen($sFilePath, 0)
    If $hFile = -1 Then ;; unable to open the file
        SetError(1)
        Return 0
    EndIf
    $aFile = FileRead($hFile, FileGetSize($sFilePath));; Read the file and remove trailing white spaces
    $aFile = StringStripWS($aFile, 2)
    FileClose($hFile)
    If StringInStr($aFile, @LF) Then
        $aArray = StringSplit(StringStripCR($aFile), @LF)
    ElseIf StringInStr($aFile, @CR) Then ;; @LF does not exist so split on the @CR
        $aArray = StringSplit($aFile, @CR)
    Else ;; unable to split the file
        SetError(1)
        Return 0
    EndIf
    Return $aArray
EndFunc   ;==>__FileReadToArray

;===============================================================================
; Function Name:   __FileWriteFromArray
; Description:      Writes Array records to the specified file.
; Syntax:           __FileWriteFromArray($File, $a_Array[, $i_Base = 0[, $i_UBound = 0[, $rEmpty = 0]]])
; Parameter(s):     $File     - String path of the file to write to, or a file handle returned from FileOpen().
;                  $a_Array  - The array to be written to the file.
;                  $i_Base   - Optional: Start Array index to read, normally set to 0 or 1. Default=0
;                  $i_Ubound - Optional: Set to the last record you want to write to the File. default=0 - whole array.
;                  $rEmpty - Optional: Remove blank lines. (default = 0 - No)
; Requirements:      None
; Return Value(s):  Success - Returns a 1
;                  Failure - Returns a 0
;                  @Error  - 0 = No error.
;                  |1 = Error opening specified file
;                  |2 = Input is not an Array
;                  |3 = Error writing to file
; Author(s):        Jos van der Zande <jdeb at autoitscript dot com>
; Modifications:    Updated for file handles by PsaltyDS at the AutoIt forums.
;                   Added ability to skip empty elements when reading from the array. - by GEOSoft.
; Note(s):          If a string path is provided, the file is overwritten and closed.
;                  To use other write modes, like append or Unicode formats, open the file with FileOpen() first
;                     and pass the file handle instead.
;                  If a file handle is passed, the file will still be open after writing.
;===============================================================================

Func __FileWriteFromArray($File, $a_Array, $i_Base = 0, $i_UBound = 0, $rEmpty = 0)
    ; Check if we have a valid array as input
    If NOT IsArray($a_Array) Then Return SetError(2, 0, 0)
    If $rEmpty < 0 Then $rEmpty = 0

    ; determine last entry
    Local $last = UBound($a_Array) - 1
    If $i_UBound < 1 OR $i_UBound > $last Then $i_UBound = $last
    If $i_Base < 0 OR $i_Base > $last Then $i_Base = 0

    ; Open output file for overwrite by default, or use input file handle if passed
    Local $hFile
    If IsString($File) Then
        $hFile = FileOpen($File, 2)
    Else
        $hFile = $File
    EndIf
    If $hFile = -1 Then Return SetError(1, 0, 0)

    ; Write array data to file
    Local $ErrorSav = 0
    FOR $x = $i_Base To $i_UBound
        ; skip empty elements (blank lines) if $rEmpty is not 0
        ;; Remove empty lines if $rEmpty is not 0
        If $rEmpty AND StringStripWS($a_Array[$x], 8) = "" Then ContinueLoop
        If FileWrite($hFile, $a_Array[$x] & @CRLF) = 0 Then
            $ErrorSav = 3
            ExitLoop
        EndIf
    Next

    ; Close file only if specified by a string path
    If IsString($File) Then FileClose($hFile)

    ; Return results
    If $ErrorSav Then
        Return SetError($ErrorSav, 0, 0)
    Else
        Return 1
    EndIf
EndFunc   ;==>__FileWriteFromArray

;===============================================================================
; Function Name:    _File_Compare()
; Description:      Performs a string comparison of 2 files
; Syntax:           _File_Compare($sFile_1, $sFile_2, $iWSpace = 0)
; Parameter(s):     $sFile_1 - full path and name of the first file
;                   $sFile_2 - full path and name of the second file
;                   $iWSpace - 0 (default) = do not ignore whitespaces
;                        - anything except 0 = ignore whitespaces
; Requirements:     None
; Return Value(s):  Success = True if the files are identical
;                             False if they are different
;                   Failure - Returns -1 and sets @Error to 1 (invalid file names)
; Author(s):        George (GEOSoft) Gedye
; Modifications:    Now allows you to ignor whitespace differences
; Notes:            The time required to compare depends on the file size and your system
;===============================================================================

Func _File_Compare($sFile_1, $sFile_2, $iWSpace = 0)
    If FileExists($sFile_1) AND FileExists($sFile_2) Then ;; Make sure they are valid file paths
        If $iWSpace = 0 Then
            Return FileRead($sFile_1) = FileRead($sFile_2)
        Else
            Return StringStripWS(FileRead($sFile_1), 8) = StringStripWS(FileRead($sFile_2), 8)
        EndIf
    Else ;; one of the files does not exist
        SetError(1)
        Return -1
    EndIf
EndFunc   ;==>_File_Compare

;===============================================================================
; Function Name:    _File_CompareDate()
; Description:      Performs a comparison of 2 file dates
; Syntax:           _File_Compare($s_Vers1, $s_Vers2)
; Parameter(s):     $cFile_1 - full path and name of the first file
;                   $cFile_2 - full path and name of the second file
; Requirements:      None
; Return Value(s):  Success = Returns an array where array[0] = newest file and array[1] = oldest file
;                   Failure - Returns 0 and sets @Error to 1 (invalid file names)
; Author(s):        George (GEOSoft) Gedye
; Modifications:
; Notes:
;===============================================================================

Func _File_CompareDate($cFile_1, $cFile_2)
    Local $rVal
    If FileExists($cFile_1) AND FileExists($cFile_2) Then ;; Make sure they are valid file paths
        $dVal_1 = StringTrimRight(FileGetTime($cFile_1, 0, 1), 2) ;; ignore seconds
        $dVal_2 = StringTrimRight(FileGetTime($cFile_2, 0, 1), 2)
        If $dVal_1 - $dVal_2 <= 0 Then
            $nFile = $cFile_2
            $oFile = $cFile_1
        Else
            $nFile = $cFile_1
            $oFile = $cFile_2
        EndIf
        Dim $rtn[2] = [$nFile, $oFile]
        Return $rtn
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc   ;==>_File_CompareDate

;===============================================================================
; Function Name:    _File_Compare_MD5()
; Description:      Performs a string comparison of 2 files
; Syntax:           _File_Compare($sFile_1, $sFile_2, $iWSpace = 0)
; Parameter(s):     $sFile_1 - full path and name of the first file
;                   $sFile_2 - full path and name of the second file
; Requirements:     None
; Return Value(s):  Success = True if the files are identical
;                             False if they are different
;                   Failure - Returns -1 and sets @Error to 1 (invalid file names)
; Author(s):        George (GEOSoft) Gedye
; Modifications:    Now allows you to ignor whitespace differences
; Notes:            The time required to compare depends on the file size and your system
;===============================================================================

Func _File_Compare_MD5($sFile_1, $sFile_2)
    Local $BufferSize = 0x20000
    Global $_MD5CodeBuffer
    If (NOT FileExists($sFile_1)) OR (NOT FileExists($sFile_2)) Then Return SetError(1, 1, 0)
    $sFile = $sFile_1
    $MD5CTX = _MD5Init()
    $hFile = FileOpen($sFile, 16)
    FOR $I = 1 To Ceiling(FileGetSize($sFile) / $BufferSize)
        _MD5Input($MD5CTX, FileRead($hFile, $BufferSize))
    Next
    $Hash_1 = _MD5Result($MD5CTX)
    FileClose($hFile)
    $sFile = $sFile_2
    $MD5CTX = _MD5Init()
    $hFile = FileOpen($sFile, 16)
    FOR $I = 1 To Ceiling(FileGetSize($sFile) / $BufferSize)
        _MD5Input($MD5CTX, FileRead($hFile, $BufferSize))
    Next
    $Hash_2 = _MD5Result($MD5CTX)
    FileClose($hFile)
    Return $Hash_1 = $Hash_2
EndFunc   ;==>_File_Compare_MD5

;===============================================================================
; Function Name:    _File_CompareVersion()
; Description:      Performs an integer comparison of the versions of 2 files
; Syntax:           _File_CompareVersion($s_Vers1, $s_Vers2)
; Parameter(s):     $iFile_1 - full path and name of the first file
;                   $iFile_2 - full path and name of the second file
; Requirements:      None
; Return Value(s):  Success = 1 if $iFile_1 is higher , 2 if $iFile_2 is higher, 0 if they are the same
;                   Failure - Returns -1 and sets @Error to
;                         [1 - if blank values were given for $fVer_1 or $fVer_2
;                         [2 - if the given values were not numeric
; Author(s):        George (GEOSoft) Gedye
; Modifications:
; Notes:            None
;===============================================================================

Func _File_CompareVersion($iFile_1, $iFile_2)
    Local $v_Rtn
    If $iFile_1 = "" OR $iFile_1 = "" Then ;; blank values are not accepted
        SetError(1)
        Return -1
    EndIf
    $fVer_1 = StringReplace(FileGetVersion($iFile_1), ",", ".")
    $fVer_2 = StringReplace(FileGetVersion($iFile_2), ",", ".")
    $fVer_1 = Number(StringReplace(FileGetVersion($iFile_1), ".", ""))
    $fVer_2 = Number(StringReplace(FileGetVersion($iFile_2), ".", ""))
    If StringLen($fVer_1) <> StringLen($fVer_2) Then
        If StringLen($fVer_1) < StringLen($fVer_2) Then ;; make sure we compare apples with apples
            Do
                $fVer_1 *= 10
            Until StringLen($fVer_1) = StringLen($fVer_2)
        Else
            Do
                $fVer_2 *= 10
            Until StringLen($fVer_1) = StringLen($fVer_2)
        EndIf
    EndIf
    If IsNumber($fVer_1) AND IsNumber($fVer_2) Then
        If $fVer_1 > $fVer_2 Then
            $v_Rtn = 1
        ElseIf $fVer_1 < $fVer_2 Then
            $v_Rtn = 2
        Else
            $v_Rtn = 0
        EndIf
        Return $v_Rtn
    Else
        SetError(2)
        Return -1
    EndIf
EndFunc   ;==>_File_CompareVersion

;===============================================================================
; Function Name:   _File_CountLines()
; Description:     Count the number of lines in a file or string of text
; Syntax:          _File_CountLines("full path and file name" OR "text block" to count)
; Parameter(s):    $sFile - A block of text or a fully qualified file path
; Requirement(s):
; Return Value(s): - Success - Line count
;                  - Failure -None
; Author(s):       George (GEOSoft) Gedye
; Modification(s):
; Note(s):
; Example(s):
#cs
    _File_CountLines(@ScriptFullPath)
#ce
;===============================================================================

Func _File_CountLines($sFile)
    If FileExists($sFile) Then $sFile = FileRead($sFile)
    StringRegExpReplace($sFile, "\v{1,2}|$", "")
    Return @Extended
EndFunc   ;==>_File_CountLines

;===============================================================================
; Function Name:   _File_CountLines2()
; Description:     Count the number of lines in a file (fast)
; Syntax:          _File_CountLines("full path and file name")
; Parameter(s):    $sFile - A fully qualified file path
;                  $iSkipEmpty - If 0 (default) or -1 or False or Default Then empty lines
;                  are counted otherwise empty lines are skipped.
; Requirement(s):
; Return Value(s): - Success - Line count
;                  - Failure - Sets @Error to 1 if unable to read the file
; Author(s):       George (GEOSoft) Gedye
; Modification(s):
; Note(s):
; Example(s):
#cs
    FileDelete(@ScriptDir & "\lines.txt")
    Local $String = ""
    FOR $I = 1 To 10000
		$String &= "Line " & $I & @CRLF
    Next
    FileWrite(@ScriptDir & "\lines.txt", StringStripWS($String, 2))
    $sFile = @ScriptDir & "\lines.txt"
    $StartTime = TimerInit()
    $iLines = _File_CountLines2($sFile, 1)
    If NOT @Error Then
		MsgBox(0, "Result", $iLines & " Lines" & @CRLF & @CRLF & Round(TimerDiff($StartTime) / 1000, 3) & " Seconds")
    Else
		MsgBox(0, "Error", "There was a problem reading the file" & @CRLF & $sFile)
    EndIf
#ce
;===============================================================================

Func _File_CountLines2($s_File, $iSkipEmpty = 0)
    Local $sStr = FileRead($s_File)
    If NOT @Extended Then Return SetError(1)
    Local $sVSpace = "\v{1,2}"
    If NOT StringRegExp($iSkipEmpty, "(?i)-1|default|0|false") Then $sVSpace = "\v+"
    StringRegExpReplace($sStr, $sVSpace & "|$", @CRLF)
    Return @Extended
EndFunc   ;==>_File_CountLines2

;===============================================================================
; Function Name:    _File_Ext_PropertiesGet()
; Description:      Get the extended properties information of a document, image,
;                    audio or video file
; Syntax:           _File_Ext_PropertiesGet("Full path and file name", "detail" [, $wName])
; Parameter(s):     $sFile - The full path and file name to check
;                   $sDetail - The required extended property (See Notes)
;                   $wName - If not = 0 then the name of the extended property will
;                             be returned in front of the actual value in the form of
;                             "Property : " and then the value of the property
; Requirements:
; Return Value(s):  Success - Returns the extended file property
;                   Failure Sets @Error
;                   [1 - The extended property requested is unknown (check spelling)
;                   [2 - The property requested is not available for the file. Example, trying to check
;                             "Dimensions" of a text document or "Duration" of an image.
;                   [3 - Invalid file path/name
; Author(s):        George (GEOSoft) Gedye
;
; Notes: Valid properties are;
;                     Name, Size, Type, Status, Owner, Author, Title, Subject,
;                     Category, Pages, Comments, Copyright,
;                     Artist, Album Title, Year, Track Number, Genre, Duration,
;                     Bit Rate, Protected, Camera, Date Taken,
;                     Dimensions, Episode, Company, Description, File Version,
;                     Sample Size, Sample Rate,
;                     Product Name, Product Version, Audio Channels, All
;                     I have left some out that are easier to get using standard
;                     AutoIt functions, e.g. FileGetAttrib()
;                     If "All" is used then an @CRLF delimited list of all the available
;                      properties (including the property name) is returned.
;
; Modifications: Added a check to see if the file is actaully just a link.
;                Changed the file path method
;                Fixed the return for "All". Now returns only available properties
;===============================================================================

Func _File_Ext_PropertiesGet($sFile, $sDetail, $wName = 0)
    If NOT FileExists($sFile) Then
        If FileExists(FileGetShortName($sFile & ".lnk")) Then
            $sc = FileGetShortcut($sFile)
            $sFile = $sc[0]
        Else
            Return SetError(3, 3, "The file " & FileGetLongName($sFile) & " does not exist")
        EndIf
    EndIf
    $sFile = StringSplit($sFile, "\")
    Local $fName = $sFile[$sFile[0]], $Path = "", $All, $Dtl, $rtn = "", $I
    FOR $I = 1 To $sFile[0] - 1
        $Path &= $sFile[$I] & "\"
    Next
    $objShell = ObjCreate("Shell.Application")
    Local $objFolder = $objShell.Namespace(StringTrimRight($Path, 1))
    Switch $sDetail
        Case "Name"
            $Dtl = 0
        Case "Size"
            $Dtl = 1
        Case "Type"
            $Dtl = 2
        Case "Status"
            $Dtl = 7
        Case "Owner"
            $Dtl = 8
        Case "Author"
            $Dtl = 9
        Case "Title"
            $Dtl = 10
        Case "Subject"
            $Dtl = 11
        Case "Category"
            $Dtl = 12
        Case "Pages"
            $Dtl = 13
        Case "Comments"
            $Dtl = 14
        Case "Copyright"
            $Dtl = 15
        Case "Artist"
            $Dtl = 16
        Case "Album Title"
            $Dtl = 17
        Case "Year"
            $Dtl = 18
        Case "Track Number"
            $Dtl = 19
        Case "Genre"
            $Dtl = 20
        Case "Duration"
            $Dtl = 21
        Case "Bit Rate"
            $Dtl = 22
        Case "Protected"
            $Dtl = 23
        Case "Camera"
            $Dtl = 24
        Case "Date Taken"
            $Dtl = 25
        Case "Dimensions"
            $Dtl = 26
        Case "Episode"
            $Dtl = 29
        Case "Company"
            $Dtl = 30
        Case "Description"
            $Dtl = 30
        Case "File Version", "Sample Size"
            $Dtl = 32
        Case "Product Name", "Sample Rate"
            $Dtl = 33
        Case "Product Version", "Audio Channels"
            $Dtl = 34
        Case "All"
            $All = StringSplit("0,1,2,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,29,30,32,33,34", ",")
        Case Else
            Return SetError(1, 1, "Unrecognized property")
    EndSwitch
    If NOT IsArray($All) Then
        FOR $Filename In $objFolder.Items
            If $objFolder.GetDetailsOf($Filename, 0) = $fName Then
                $rtn = $objFolder.GetDetailsOf($Filename, $Dtl)
                If $rtn = "" Then Return SetError(2, 2, "Property " & $objFolder.GetDetailsOf($objFolder.Items, $Dtl) & " is unknown for this file")
                If $wName <> 0 Then $rtn = $objFolder.GetDetailsOf($objFolder.Items, $Dtl) & " : " & $rtn
                Return String($rtn)
            EndIf
        Next
    Else
        FOR $Filename In $objFolder.Items
            If $objFolder.GetDetailsOf($Filename, 0) = $fName Then
                FOR $I = 1 To $All[0]
                    If $objFolder.GetDetailsOf($Filename, $All[$I]) = "" Then ContinueLoop
                    $rtn &= $objFolder.GetDetailsOf($objFolder.Items, $All[$I]) & " : " & $objFolder.GetDetailsOf($Filename, $All[$I]) & @CRLF
                Next
            EndIf
        Next
        Return StringStripWS($rtn, 2)
    EndIf
EndFunc   ;==>_File_Ext_PropertiesGet

;===============================================================================
; Function Name:    _File_GetDate()
; Description:      Reads a text file and returns an array where each element contains a line of text
; Syntax:           _File_GetDate($sFilePath)
; Parameter(s):     $sFilePath - Path and filename of the file to check
; Requirements:      None
; Return Value(s):  On Success - Returns a formatted date string suitable for use with the _Date functions. e.g.
;                                  4 digit year/2 digit month/2 digit day (2008/04/17)
; Author(s):        George (GEOSoft) Gedye
; Modifications:
; Notes:            None
;===============================================================================

Func _File_GetDate($sFilePath)
    $sFilePath = FileGetShortName($sFilePath)
    $fTime = FileGetTime($sFilePath, 1)
    Return StringFormat("%04d/%02d/%02d", $fTime[0], $fTime[1], $fTime[2])
EndFunc   ;==>_File_GetDate

;===============================================================================
; Function Name:   _File_GetOwner()
; Description:   Retrieve the ownership of a file
; Syntax:   _File_GetOwner("FULL path and filename", "computer name")
; Parameter(s):
; Requirement(s):
; Return Value(s):   Success - Returns name or group of the file owner
;                    Failure - Returns 0 if file not found (@Error = 0)
;                              Sets @Error to 1 if
;                                   unable to connect to the object
;
; Author(s):   George (GEOSoft) Gedye
; Modification(s):
; Note(s):   Also works on folders
; Example(s):
;===============================================================================

Func _File_GetOwner($sFile, $sComputer = "localhost")
    Local $Obj, $Item, $Items, $rVal = ""
    If StringRight($sFile, 1) = "\" Then $sFile = StringTrimRight($sFile, 1)
    $sComputer = StringReplace($sComputer, "\", "")
    $Obj = ObjGet("winmgmts:\\" & $sComputer & "\root\cimv2")
    If IsObj($Obj) Then
        $Items = $Obj.ExecQuery _
                ("ASSOCIATORS OF {Win32_LogicalFileSecuritySetting='" & $sFile & "'}" & _
                " WHERE AssocClass=Win32_LogicalFileOwner ResultRole=Owner")
        FOR $Item In $Items
            If $Item.ReferencedDomainName Then
                $rVal = $Item.AccountName
            EndIf
        Next
    Else
        SetError(1)
    EndIf
    Return $rVal
EndFunc   ;==>_File_GetOwner

;===============================================================================
; Function Name:   _File_MoveByDate()
; Description:     Use to move or copy files by date created
; Syntax:          _File_MoveByDate($sPath, $sNewPath[, $sPattern = "*"[, $iDate = -1[, $iDateFlag = 1[, $iMove = 1[, $iOverWrite = 1]]]]])
; Parameter(s):    $sPath - the folder to search
;                  $sNewPath - The folder where the files should be moved/copied to
;                  $sPattern - File search pattern.  Default is all
;                  $iDate (optional) - The date to start checking in the format YYYYMMDD. Default is current day
;                  $iDateFlag (optional)- see FileGetTime() for possible values,  Default is 0 (Last Modified)
;                  $iMove (optional) - If not 1 then a copy operation will be performed instead of a move
;                  $iOverWrite (optional) - If 1 (default) then an existing file of the same name will be over-written
;                  $iNewer (optional) - If 1 (default) operation performed on files equal to or newer than $iDate
;                                        else operation performed on files equal to or older than $iDate
; Requirement(s):
; Return Value(s): - Success - Returns the count of files copied or moved
;                  - Failure - Sets @Error to
;                                   1 - If no files match the pattern
;                                   2 - If the source folder path does not exist
;                                   3 - if unable to create the destination folder
; Author(s):       George (GEOSoft) Gedye
; Modification(s): Added $iNewer parameter (see parameters) 2009/04/04
; Note(s):
; Example(s):
#cs
    $sFldr = @ScriptDir & "\"
    $sFldr2 = @DeskTopDir & "\Test Folder\"
    $iMoved = _File_MoveByDate($sFldr, $sFldr2)
    If NOT @Error Then
    MsgBox(0, "Finished", $iMoved & " files were moved or copied")
    If $iMoved Then ShellExecute($sFldr2)
    EndIf
#ce
;===============================================================================

Func _File_MoveByDate($sPath, $sNewPath, $sPattern = "*", $iDate = -1, _
        $iDateFlag = 0, $iMove = 1, $iOverWrite = 1, $iNewer = 1)
    Local $sHold, $aCreated, $iCreated, $iCount = 0, $iValid
    If StringRight($sPath, 1) <> "\" Then $sPath &= "\"
    If NOT FileExists($sPath) Then Return SetError(2)
    If StringRight($sNewPath, 1) <> "\" Then $sNewPath &= "\"
    If $iDateFlag > 2 OR $iDateFlag < 0 Then $iDateFlag = 1
    If NOT FileExists($sNewPath) Then
        If NOT DirCreate($sNewPath) Then Return SetError(3)
    EndIf
    If $iDate = -1 Then $iDate = @YEAR & @MON & @MDAY
    $sFile = FileFindFirstFile($sPath & $sPattern)
    If NOT @Error Then
        If NOT FileExists($sNewPath) Then DirCreate($sNewPath)
        If $iOverWrite <> 1 Then $iOverWrite = 0
        While 1
            $iValid = False
            $sHold = FileFindNextFile($sFile)
            If @Error Then ExitLoop
            If StringInStr(FileGetAttrib($sPath & $sHold), "D") Then ContinueLoop
            $aCreated = FileGetTime($sPath & $sHold, $iDateFlag)
            $iCreated = $aCreated[0] & $aCreated[1] & $aCreated[2]
            If $iNewer = 1 Then
                If $iCreated >= $iDate Then $iValid = True
            Else
                If $iCreated <= $iDate Then $iValid = True
            EndIf
            If $iValid Then
                If $iMove = 1 Then
                    If NOT FileMove($sPath & $sHold, $sNewPath & $sHold, $iOverWrite) Then
                        MsgBox(4096, "File Error", "Unable to Move The File " & $sHold, 5)
                        ContinueLoop
                    EndIf
                Else
                    If NOT FileCopy($sPath & $sHold, $sNewPath & $sHold, $iOverWrite) Then
                        MsgBox(4096, "File Error", "Unable to Copy The File " & $sHold, 5)
                        ContinueLoop
                    EndIf
                EndIf
                $iCount += 1
            EndIf
        WEnd
    Else
        Return SetError(1)
    EndIf
    Return $iCount
EndFunc   ;==>_File_MoveByDate

;===============================================================================
; Function Name:   _File_ReadFromLine()
; Description:     _File_ReadFromLine($sStr, $iLine)
; Syntax:
; Parameter(s):    $sStr = a string or the full path to a file to be read
;                  $iLine = Line to begin reading from
; Requirement(s):
; Return Value(s): - Success The contents starting at the specified line number
;                  - Failure
; Author(s):       George (GEOSoft) Gedye
; Modification(s):
; Note(s):    Thanks To SmOke_N for his help on the RegExp
; Example(s):
#cs
    $String = _File_ReadFromLine("C:\somefile.txt", 8); Will start reading from Line 8
    ClipPut($String)
#ce
;===============================================================================

Func _File_ReadFromLine($sStr, $iLine)
    If $sStr = "" Then Return SetError(1, 0, "")
    If FileExists($sStr) Then $sStr = FileRead($sStr)
    $iLine = Int($iLine)
    If $iLine <= 1 Then Return $sStr
    Local $sRegEx = "(?s)^(.*?(?:\r\n|\r|\n)){" & $iLine & "}(.+?)\z"
    Local $aRegEx = StringRegExp($sStr, $sRegEx, 1)
    If @Error Then Return SetError(2, 0, "")
    Return $aRegEx[1]
EndFunc   ;==>_File_ReadFromLine

;===============================================================================
; Function Name:     _File_SetOwner()
; Description:      Set the ownership of a file or folder to the current user
; Syntax:   _File_SetOwner("path & filename" [, "Computer name"[, require admin)
; Parameter(s):   $sFile
;                 $Computer - (optional) name of the computer to run against
;                 $rAdmin - (optional) if 1 then Requires Administrator privledges.
; Requirement(s):
; Return Value(s): Success - returns 0
;                  Failure - returns 1 and sets @Error to 2
;                          - Sets @Error to 1 if $rAdmin = 1 and user is not an admin
; Author(s):   George (GEOSoft) Gedye
; Modification(s):
; Note(s):   If run against a folder then ownership of the files inside will also change
; Example(s):
;===============================================================================

Func _File_SetOwner($sFile, $Computer = "localhost", $rAdmin = 1)
    If $rAdmin > 1 OR $rAdmin < 0 Then $rAdmin = 1
    If $rAdmin = 1 AND IsAdmin() = 0 Then Return SetError(1)
    $Computer = StringReplace($Computer, "\", "")
    $Obj = ObjGet("winmgmts:\\" & $Computer & "\root\cimv2")
    If IsObj($Obj) Then
        $oFile = $Obj.Get("CIM_DataFile.Name='" & $sFile & "'")
        $Result = Int($oFile.TakeOwnership)
        Return $Result
    Else
        Return SetError(2)
    EndIf
EndFunc   ;==>_File_SetOwner

;** Private Functions **********************
Func _MD5Init()
    Local $_MD5Opcode = '0xC85800005356576A006A006A008D45A850E8280000006A00FF750CFF75088D45A850E8440000006A006A008D45A850FF7510E8710700005F5E5BC9C210005589E58B4D0831C0894114894110C70101234567C7'
    $_MD5Opcode &= '410489ABCDEFC74108FEDCBA98C7410C765432105DC21000C80C0000538B5D088B4310C1E80383E03F8945F88B4510C1E0030143103943107303FF43148B4510C1E81D0143146A40582B45F88945F4394510724550FF75'
    $_MD5Opcode &= '0C8B45F88D44031850E8A00700008D43185053E84E0000008B45F48945FC8B45FC83C03F39451076138B450C0345FC5053E8300000008345FC40EBE28365F800EB048365FC008B45102B45FC508B450C0345FC508B45F8'
    $_MD5Opcode &= '8D44031850E84D0700005BC9C21000C84000005356576A40FF750C8D45C050E8330700008B45088B088B50048B70088B780C89D021F089D3F7D321FB09D801C1034DC081C178A46AD7C1C10701D189C821D089CBF7D321F'
    $_MD5Opcode &= '309D801C7037DC481C756B7C7E8C1C70C01CF89F821C889FBF7D321D309D801C60375C881C6DB702024C1C61101FE89F021F889F3F7D321CB09D801C20355CC81C2EECEBDC1C1C21601F289D021F089D3F7D321FB09D801'
    $_MD5Opcode &= 'C1034DD081C1AF0F7CF5C1C10701D189C821D089CBF7D321F309D801C7037DD481C72AC68747C1C70C01CF89F821C889FBF7D321D309D801C60375D881C6134630A8C1C61101FE89F021F889F3F7D321CB09D801C20355DC'
    $_MD5Opcode &= '81C2019546FDC1C21601F289D021F089D3F7D321FB09D801C1034DE081C1D8988069C1C10701D189C821D089CBF7D321F309D801C7037DE481C7AFF7448BC1C70C01CF89F821C889FBF7D321D309D801C60375E881C6B1'
    $_MD5Opcode &= '5BFFFFC1C61101FE89F021F889F3F7D321CB09D801C20355EC81C2BED75C89C1C21601F289D021F089D3F7D321FB09D801C1034DF081C12211906BC1C10701D189C821D089CBF7D321F309D801C7037DF481C7937198FD'
    $_MD5Opcode &= 'C1C70C01CF89F821C889FBF7D321D309D801C60375F881C68E4379A6C1C61101FE89F021F889F3F7D321CB09D801C20355FC81C22108B449C1C21601F289D021F889FBF7D321F309D801C1034DC481C162251EF6C1C1050'
    $_MD5Opcode &= '1D189C821F089F3F7D321D309D801C7037DD881C740B340C0C1C70901CF89F821D089D3F7D321CB09D801C60375EC81C6515A5E26C1C60E01FE89F021C889CBF7D321FB09D801C20355C081C2AAC7B6E9C1C21401F289D02'
    $_MD5Opcode &= '1F889FBF7D321F309D801C1034DD481C15D102FD6C1C10501D189C821F089F3F7D321D309D801C7037DE881C753144402C1C70901CF89F821D089D3F7D321CB09D801C60375FC81C681E6A1D8C1C60E01FE89F021C889CBF7'
    $_MD5Opcode &= 'D321FB09D801C20355D081C2C8FBD3E7C1C21401F289D021F889FBF7D321F309D801C1034DE481C1E6CDE121C1C10501D189C821F089F3F7D321D309D801C7037DF881C7D60737C3C1C70901CF89F821D089D3F7D321CB0'
    $_MD5Opcode &= '9D801C60375CC81C6870DD5F4C1C60E01FE89F021C889CBF7D321FB09D801C20355E081C2ED145A45C1C21401F289D021F889FBF7D321F309D801C1034DF481C105E9E3A9C1C10501D189C821F089F3F7D321D309D801C7037'
    $_MD5Opcode &= 'DC881C7F8A3EFFCC1C70901CF89F821D089D3F7D321CB09D801C60375DC81C6D9026F67C1C60E01FE89F021C889CBF7D321FB09D801C20355F081C28A4C2A8DC1C21401F289D031F031F801C1034DD481C14239FAFFC1C1040'
    $_MD5Opcode &= '1D189C831D031F001C7037DE081C781F67187C1C70B01CF89F831C831D001C60375EC81C622619D6DC1C61001FE89F031F831C801C20355F881C20C38E5FDC1C21701F289D031F031F801C1034DC481C144EABEA4C1C10401'
    $_MD5Opcode &= 'D189C831D031F001C7037DD081C7A9CFDE4BC1C70B01CF89F831C831D001C60375DC81C6604BBBF6C1C61001FE89F031F831C801C20355E881C270BCBFBEC1C21701F289D031F031F801C1034DF481C1C67E9B28C1C10401D1'
    $_MD5Opcode &= '89C831D031F001C7037DC081C7FA27A1EAC1C70B01CF89F831C831D001C60375CC81C68530EFD4C1C61001FE89F031F831C801C20355D881C2051D8804C1C21701F289D031F031F801C1034DE481C139D0D4D9C1C10401D189C'
    $_MD5Opcode &= '831D031F001C7037DF081C7E599DBE6C1C70B01CF89F831C831D001C60375FC81C6F87CA21FC1C61001FE89F031F831C801C20355C881C26556ACC4C1C21701F289F8F7D009D031F001C1034DC081C1442229F4C1C10601D189F'
    $_MD5Opcode &= '0F7D009C831D001C7037DDC81C797FF2A43C1C70A01CF89D0F7D009F831C801C60375F881C6A72394ABC1C60F01FE89C8F7D009F031F801C20355D481C239A093FCC1C21501F289F8F7D009D031F001C1034DF081C1C3595B65C'
    $_MD5Opcode &= '1C10601D189F0F7D009C831D001C7037DCC81C792CC0C8FC1C70A01CF89D0F7D009F831C801C60375E881C67DF4EFFFC1C60F01FE89C8F7D009F031F801C20355C481C2D15D8485C1C21501F289F8F7D009D031F001C1034DE0'
    $_MD5Opcode &= '81C14F7EA86FC1C10601D189F0F7D009C831D001C7037DFC81C7E0E62CFEC1C70A01CF89D0F7D009F831C801C60375D881C6144301A3C1C60F01FE89C8F7D009F031F801C20355F481C2A111084EC1C21501F289F8F7D009D031'
    $_MD5Opcode &= 'F001C1034DD081C1827E53F7C1C10601D189F0F7D009C831D001C7037DEC81C735F23ABDC1C70A01CF89D0F7D009F831C801C60375C881C6BBD2D72AC1C60F01FE89C8F7D009F031F801C20355E481C291D386EBC1C21501F28B4'
    $_MD5Opcode &= '508010801500401700801780C5F5E5BC9C20800C814000053E840000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    $_MD5Opcode &= '000000008F45EC8B5D0C6A088D4310508D45F850E8510000008B4310C1E80383E03F8945F483F838730B6A38582B45F48945F0EB096A78582B45F48945F0FF75F0FF75ECFF750CE831F8FFFF6A088D45F850FF750CE823F8'
    $_MD5Opcode &= 'FFFF6A1053FF7508E8050000005BC9C210005589E55156578B7D088B750C8B4D10FCF3A45F5E595DC20C00'

    If NOT IsDllStruct($_MD5CodeBuffer) Then
        $_MD5CodeBuffer = DllStructCreate("byte[" & BinaryLen($_MD5Opcode) & "]")
        DllStructSetData($_MD5CodeBuffer, 1, $_MD5Opcode)
    EndIf

    Local $OpcodeStart = 62

    Local $MD5CTX = DllStructCreate("dword[22]")
    DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_MD5CodeBuffer) + $OpcodeStart, _
            "ptr", DllStructGetPtr($MD5CTX), _
            "int", 0, _
            "int", 0, _
            "int", 0)

    $CodeBuffer = 0
    Return $MD5CTX
EndFunc   ;==>_MD5Init

Func _MD5Input(ByRef $MD5CTX, $Data)
    If NOT IsDllStruct($_MD5CodeBuffer) Then Return

    Local $OpcodeStart = 107

    Local $Input = DllStructCreate("byte[" & BinaryLen($Data) & "]")
    DllStructSetData($Input, 1, $Data)

    DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_MD5CodeBuffer) + $OpcodeStart, _
            "ptr", DllStructGetPtr($MD5CTX), _
            "ptr", DllStructGetPtr($Input), _
            "int", BinaryLen($Data), _
            "int", 0)

    $Input = 0
EndFunc   ;==>_MD5Input

Func _MD5Result(ByRef $MD5CTX)
    If NOT IsDllStruct($_MD5CodeBuffer) Then Return Binary(0)

    ;Local $OpcodeStart = (StringInStr($_MD5Opcode, "C814000053") - 1) / 2 - 1
    Local $OpcodeStart = 1960

    Local $Digest = DllStructCreate("byte[16]")

    DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($_MD5CodeBuffer) + $OpcodeStart, _
            "ptr", DllStructGetPtr($Digest), _
            "ptr", DllStructGetPtr($MD5CTX), _
            "int", 0, _
            "int", 0)

    Local $Ret = DllStructGetData($Digest, 1)
    $CodeBuffer = 0
    $Digest = 0
    $MD5CTX = 0
    $_MD5CodeBuffer = 0
    Return StringLower($Ret)
EndFunc   ;==>_MD5Result