Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/08/2014 in all areas

  1. czardas

    Fraction

    Perform accurate division using real fractions and convert floating point numbers to fractions. Floating point arithmetic often introduces small inaccuracies. Most of the time this is not a problem, but sometimes it can be. As a workaround, many programmers decide to only use whole numbers for specific calculations - ones which need to return exact results. The fraction 1/3 cannot be represented using a float. You would need a decimal (or floating point variant) of infinite length to give an accurate representation of 1/3. Working with fractions is not entirely straight forward, and at times this can be a little frustrating. With the functions in this library, there is potential for internal calculations to produce numbers which are out of range. Not withstanding oversights: both input numbers should be less than 16 digits and the difference between the denominator and the divisor should be an order of magnitude less than 10^16, otherwise the function will return an error. With the exception of Fraction(), all included functions take array parameters. All return values are either arrays or boolean values. Documentation and examples pending. NEW VERSION requires operator64.au3 found here: https://www.autoitscript.com/forum/topic/176620-operator64/ This is an alpha release -see post 33. #include-once #include 'operator64.au3' ; #INDEX# ====================================================================================================================== ; Title .........: Fraction ; AutoIt Version : 3.3.14.0 ; Language ......: English ; Description ...: Maths functions intended to be used with vulgar fractions. ; Notes .........: In this library, a fraction is defined as two integers stored in a two element array. ; Several functions use approximation when internal calculations go out of range. ; When an approximation occurs, @extended is set to 1. This return value should be checked in most instances. ; ----------------------------------------------------------------------------------------------------------- ; Input Size Limits for _Fraction() ; Unlimited within the confines of AutoIt (approximately) between -1e+308 and +1e+308 ; Smallest value (approximately) 1e-323 ; -------------------------------------------------------------------- ; Negative Output Size Limits for All Functions That Return a Fraction ; 9223372036854775807 /-1 To -1/ 9223372036854775807 negative range ; - 2^63 /1 Out of range ; tiny negative values are either rounded down to -1/ 9223372036854775807 or rounded up to 0/-1 ; ---------------------------------------------------------------- ; Positive Output Size Limits for Functions That Return a Fraction ; 1/ 9223372036854775807 To 9223372036854775807 /1 positive range ; 2^63 /1 Out of range ; tiny positive values are either rounded up to 1/ 9223372036854775807 or rounded down to 0/1 ; Author(s) .....: czardas, Pheonix XL ; ============================================================================================================================== ; #CURRENT# ==================================================================================================================== ; _Fraction ; _FractionAbs ; _FractionAdd ; _FractionApproximate ; _FractionCeiling ; _FractionDivide ; _FractionFloor ; _FractionMod ; _FractionMultiply ; _FractionPower ; _FractionRoot ; _FractionSubtract ; _IsFraction ; _IsFractionNegative ; _Reciprocal ; ============================================================================================================================== ; #INTERNAL_USE_ONLY#=========================================================================================================== ; __GCD ; __FloatRatio ; __FloatToDigits ; __Quotient ; __Simplify ; ============================================================================================================================== ; #FUNCTION# =================================================================================================================== ; Name...........: _Fraction ; Description ...: Conversion from float to fraction and whole number division. ; Syntax.........: _Fraction($nDividend [, $nDivisor = 1]) ; Parameters.....; $iDividend - Top fractional part ; $iDivisor - [Optional] Lower fractional part. The default value is 1. ; Return Values ; Success - Returns an array of two elements. The first element is the dividend, and the second is the divisor. ; Sets @Extended to 1 if rounding or approximation occurs, or if one of the input parameters is a float. ; Failure sets @error as follows ; |@error = 1 Input contains non-numeric or undefined data. ; |@error = 2 The divisor cannot be zero. ; |@error = 3 Out of range. ; Author ........: czardas ; Comments ......; Accepts Int32, Int64 and floats. Output ranges are shown in the main header. ; ============================================================================================================================== Func _Fraction($nDividend, $nDivisor = 1) If Not IsNumber($nDividend) Or StringInStr($nDividend, '#') Or _ Not IsNumber($nDivisor) Or StringInStr($nDivisor, '#') Then Return SetError(1) ; non-numeric input or undefined value If $nDivisor = 0 Then Return SetError(2) ; division by zero produces meaningless results Local $iExtended = 0 ; will be set to 1 if rounding or approximation occurs, or if one of the input parameters is a float $nDividend = __Integer64($nDividend) If @error Or $nDividend = 0x8000000000000000 Then $iExtended = 1 $nDivisor = __Integer64($nDivisor) If @error Or $nDivisor = 0x8000000000000000 Then $iExtended = 1 Local $aFraction[2] ; if both the dividend and divisor are negative, then both output values will be positive $aFraction[0] = ($nDividend < 0 And $nDivisor > 0) ? -1 : 1 $aFraction[1] = ($nDivisor < 0 And $nDividend > 0) ? -1 : 1 If $iExtended Then ; float parameters require preprocessing $nDividend = Number($nDividend, 3) $nDivisor = Number($nDivisor, 3) __FloatRatio($nDividend, $nDivisor) If @error Then Return SetError(3) ; out of range EndIf If $nDividend = 0 Then $aFraction[0] = 0 $aFraction[1] = $nDivisor > 0 ? 1 : -1 ; a fraction may have a value of negative zero (purpose unknown) Return $aFraction EndIf $nDividend = _Abs64($nDividend) $nDivisor = _Abs64($nDivisor) If $nDividend <> 0 Then __Simplify($nDividend, $nDivisor) ; division by the greatest common divisor $aFraction[0] *= $nDividend ; return values may be negative $aFraction[1] *= $nDivisor ; as above. Return SetExtended($iExtended, $aFraction) EndFunc ;==> _Fraction ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionAbs ; Description ...: Calculates the absolute value of a fraction. ; Syntax.........: _FractionAbs($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing the absolute values of both dividend and divisor. ; Failure sets @error to 1 if the input is not a valid array containing both a dividend and a divisor. ; Author ........: czardas ; ============================================================================================================================== Func _FractionAbs($aFraction) If Not _IsFraction($aFraction) Then Return SetError(1) $aFraction[0] = _Abs64($aFraction[0]) $aFraction[1] = _Abs64($aFraction[1]) Return $aFraction EndFunc ;==> _FractionAbs ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionAdd ; Description ...: Calculates the sum of two fractions. ; Syntax.........: _FractionAdd($aFraction1, $aFraction2) ; Parameters.....; $aFraction1 - The first two element array containing a dividend and a divisor. ; $aFraction2 - The second two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing the sum of the two fractions. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error = 2 The divisor cannot become zero. ; |@error = 3 Out of range. ; Author ........: czardas ; ============================================================================================================================== Func _FractionAdd($aFraction1, $aFraction2) If Not (_IsFraction($aFraction1) And _IsFraction($aFraction2)) Then Return SetError(1) Local $iValue_1, $iValue_2, $iDividend, $iDivisor, $iExtended = 0 If __OverflowDetect('*', $aFraction1[0], $aFraction2[1], $iValue_1) Then $iExtended = 1 If __OverflowDetect('*', $aFraction1[1], $aFraction2[0], $iValue_2) Then $iExtended = 1 If __OverflowDetect('+', $iValue_1, $iValue_2, $iDividend) Then $iExtended = 1 If __OverflowDetect('*', $aFraction1[1], $aFraction2[1], $iDivisor) Then $iExtended = 1 Local $aAddition = _Fraction($iDividend, $iDivisor) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aAddition) EndFunc ;==> _FractionAdd ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionApproximate ; Description ...: Approximates the value of a fraction according to limits imposed on the size of the divisor. ; Syntax.........: _FractionApproximate($aFraction, $iMaxDivisor) ; Parameters.....; $aFraction - A two element array containing a valid dividend and divisor. ; $iMaxDivisor - The maximum numeric limit for the divisor. ; Return values .: Success - Returns a two element array containing the approximated fraction. ; Failure sets @error as follows ; |@error = 1 Invalid input for $aFraction. ; |@error = 2 Invalid input for $iMaxDivisor. ; Author ........: czardas ; Comments ......; Approximates fractions using the method of continued fractions. ; ============================================================================================================================== Func _FractionApproximate($aFraction, $iMaxDivisor) If Not _IsFraction($aFraction) Then Return SetError(1) Local $bNegative = @extended $iMaxDivisor = _Abs64($iMaxDivisor) If @extended Then Return SetError(2, 0, $aFraction) Local $aCurrentFraction = _FractionAbs($aFraction) If $iMaxDivisor < 1 Or $iMaxDivisor >= $aCurrentFraction[1] Or $aCurrentFraction[1] <= 1 Then Return SetError(2, 0, $aFraction) ; determine the terms of the continued fraction Local $sFractionOfFraction = '' Do $sFractionOfFraction &= __Quotient($aCurrentFraction[0], $aCurrentFraction[1]) & ',' $aCurrentFraction[0] = Mod($aCurrentFraction[0], $aCurrentFraction[1]) $aCurrentFraction = _Reciprocal($aCurrentFraction) Until @error Local $aContinued = StringSplit(StringTrimRight($sFractionOfFraction, 1), ',', 2) Local $iTry, $iRange, $iMin = 0, $iMax = Ubound($aContinued) -1, $aConvergence[2] ; binary search algorithm Do $aConvergence[0] = 0 $aConvergence[1] = 1 $iRange = $iMax - $iMin +1 $iTry = $iMin + Floor($iRange/2) If $iTry > $iMax Then $iTry = $iMax ; added patch ; evaluate the significant first few terms of the continued fraction If $iTry > 0 Then For $i = $iTry To 1 Step -1 $aConvergence = _FractionAdd($aConvergence, _Fraction(Number($aContinued[$i]))) $aConvergence = _Reciprocal($aConvergence) Next EndIf $aConvergence = _FractionAdd($aConvergence, _Fraction(Number($aContinued[0]))) If $aConvergence[1] > $iMaxDivisor Then ; aim was too high - target is lower $iMax = $iTry -1 Else ; aim was too low - target may be higher ; log low entry $aCurrentFraction = $aConvergence $iMin = $iTry +1 EndIf Until $iRange <= 1 If $bNegative Then $aCurrentFraction[(($aFraction[0] < 0) ? 0 : 1)] *= -1 Return $aCurrentFraction EndFunc ;==> _FractionApproximate ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionCeiling ; Description ...: Calculates the ceiling value of a fraction. ; Syntax.........: _FractionCeiling($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array ==> The first element is the ceiling value, and the divisor is always 1. ; Failure sets @error as follows ; |@error = 1 The input is not a valid array containing a dividend and a divisor. ; Author ........: czardas ; Comments ......; If the fraction is negative, then its ceiling value represents the integer part of the fraction. ; ============================================================================================================================== Func _FractionCeiling($aFraction) If Not _IsFraction($aFraction) Then Return SetError(1) Local $bNegative = @extended If $aFraction[0] = 0 Then Return $aFraction ; for this to work we need to simplify the fraction $aFraction = _FractionAbs($aFraction) Local $iDividend = $aFraction[0], $iDivisor = $aFraction[1] __Simplify($iDividend, $iDivisor) If $iDivisor = 1 Then Return _Fraction($iDividend * ($bNegative = 0 ? 1 : -1)) Local $iCeiling = __Quotient($iDividend, $iDivisor) If $bNegative Then Return _Fraction($iCeiling * -1) Return _Fraction($iCeiling + 1) EndFunc ;==> _FractionCeiling ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionDivide ; Description ...: Divides the first fraction by the second. ; Syntax.........: _FractionDivide($aDividend, $aDivisor) ; Parameters.....; $aDividend - The first two element array containing a dividend and a divisor. ; $aDivisor - The second two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing the result after division. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error = 2 The divisor cannot become zero. ; |@error = 3 Out of range. ; Author ........: czardas ; ============================================================================================================================== Func _FractionDivide($aDividend, $aDivisor) If Not (_IsFraction($aDividend) And _IsFraction($aDivisor)) Then Return SetError(1) Local $iValue_1, $iValue_2, $iExtended = 0 If __OverflowDetect('*', $aDividend[0], $aDivisor[1], $iValue_1) Then $iExtended = 1 If __OverflowDetect('*', $aDividend[1], $aDivisor[0], $iValue_2) Then $iExtended = 1 If $aDivisor[0] = 0 Then Return SetError(2) Local $aDivision = _Fraction($iValue_1, $iValue_2) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aDivision) EndFunc ;==> _FractionDivide ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionFloor ; Description ...: Calculates the floor value of a fraction. ; Syntax.........: _FractionFloor($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array ==> The first element is the floor value, and the divisor is always 1. ; Failure sets @error as follows ; |@error = 1 The input is not a valid array containing a dividend and a divisor. ; Author ........: czardas ; Comments ......; If the fraction is positive, then its floor value represents the integer part of the fraction. ; ============================================================================================================================== Func _FractionFloor($aFraction) If Not _IsFraction($aFraction) Then Return SetError(1) Local $bNegative = @extended If $aFraction[0] = 0 Then Return $aFraction ; for this to work we need to simplify the fraction $aFraction = _FractionAbs($aFraction) Local $iDividend = $aFraction[0], $iDivisor = $aFraction[1] __Simplify($iDividend, $iDivisor) If $iDivisor = 1 Then Return _Fraction($iDividend * ($bNegative = 0 ? 1 : -1)) Local $iFloor = __Quotient($iDividend, $iDivisor) If Not $bNegative Then Return _Fraction($iFloor) Return _Fraction($iFloor * -1 - 1) EndFunc ;==> _FractionFloor ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionMod ; Description ...: Performs the modulus operation with two fractions. ; Syntax.........: _FractionMod($aDividend, $aDivisor) ; Parameters.....; $aDividend - The first fraction is the dividend array. ; $aDivisor - The second fraction is the divisor array. ; Return values .: Success - Returns a two element array containing the modulus of $aDividend and $aDivisor. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error to: ; |@error = 1 Out of bounds - Fraction division failure. ; |@error = 2 Out of bounds - Fraction multiplication failure. ; |@error = 3 Out of bounds - Fraction subtraction failure. ; Author ........: czardas ; ============================================================================================================================== Func _FractionMod($aDividend, $aDivisor) Local $iExtended = 0, $aDivision = _FractionDivide($aDividend, $aDivisor) If @error Then Return SetError(1) If @extended Then $iExtended = @extended Local $aModulus[2] If $aDividend[0] = 0 Then $aModulus[0] = 0 $aModulus[1] = ($aDividend[0] < 0) ? -1 : 1 Return $aModulus EndIf Local $aMultiple = _FractionMultiply(_FractionAbs($aDivisor), _FractionFloor(_FractionAbs($aDivision))) If @error Then Return SetError(2) If @extended Then $iExtended = @extended $aModulus = _FractionSubtract(_FractionAbs($aDividend), $aMultiple) If @error Then Return SetError(3) If @extended Then $iExtended = @extended If _IsFractionNegative($aDividend) Then If $aDividend[0] < 0 Then $aModulus[0] *= -1 Else $aModulus[1] *= -1 EndIf EndIf Return SetExtended($iExtended, $aModulus) EndFunc ;==> _FractionMod ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionMultiply ; Description ...: Calculates the product of two fractions. ; Syntax.........: _FractionMultiply($aFraction1, $aFraction2) ; Parameters.....; $aFraction1 - The first two element array containing a dividend and a divisor. ; $aFraction2 - The second two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing the product of the two fractions. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error > 1 Internal calculations went out of range. ; Author ........: czardas ; ============================================================================================================================== Func _FractionMultiply($aFraction1, $aFraction2) If Not (_IsFraction($aFraction1) And _IsFraction($aFraction2)) Then Return SetError(1) Local $iValue_1, $iValue_2, $iExtended = 0 If __OverflowDetect('*', $aFraction1[0], $aFraction2[0], $iValue_1) Then $iExtended = 1 If __OverflowDetect('*', $aFraction1[1], $aFraction2[1], $iValue_2) Then $iExtended = 1 Local $aProduct = _Fraction($iValue_1, $iValue_2) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aProduct) EndFunc ;==> _FractionMultiply ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionPower ; Description ...: Raises a fraction to the power of a fraction. ; Syntax.........: _FractionPower($aFraction, $aPower) ; Parameters.....; $aFraction - The first two element array containing a dividend and a divisor. ; $aPower - The second two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing $aFraction to the power of $aPower. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error = 3 Out of range. ; |@error = 5 Imaginary fraction detected. ; Author ........: czardas ; Comments ......; Calculating fractional powers of approximated negative fractions leads to ambiguity. ; ============================================================================================================================== Func _FractionPower($aFraction, $aPower) If Not _IsFraction($aPower) Then Return SetError(1) Local $bNegative = _IsFractionNegative($aFraction) If @error Then Return SetError(1) If $bNegative And Mod($aPower[1], 2) = 0 Then Return SetError(5) Local $iSign = ($bNegative And Mod($aPower[0], 2) <> 0) ? -1 : 1 $aFraction = _FractionAbs($aFraction) Local $iExtended, $iPower = __WholeNumberDivision($aPower[0], $aPower[1]) If @extended Then $iExtended = 1 Local $iDividend If $iExtended Then $iDividend = $aFraction[0] ^ $iPower Else $iDividend = _Power64($aFraction[0], $iPower) If @extended Then $iExtended = 1 EndIf Local $iDivisor If $iExtended Then $iDivisor = $aFraction[1] ^ $iPower Else $iDivisor = _Power64($aFraction[1], $iPower) If @extended Then $iExtended = 1 EndIf $aPower = _Fraction($iSign * $iDividend, $iDivisor) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aPower) EndFunc ;==> FractionPower ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionRoot ; Description ...: Calculates the fractional root of a fraction. ; Syntax.........: _FractionRoot($aFraction, $aRoot) ; Parameters.....; $aFraction - The first two element array containing a dividend and a divisor. ; $aRoot - The second two element array containing a dividend and a divisor. ; Return values .: Success - Returns a two element array containing $aFraction to the power of the reciprocal of $aRoot. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error = 3 Out of range. ; |@error = 5 Imaginary fraction detected. ; Author ........: czardas ; Comments ......; Calculating fractional roots of approximated negative fractions leads to ambiguity. ; ============================================================================================================================== Func _FractionRoot($aFraction, $aRoot) If Not _IsFraction($aRoot) Then Return SetError(1) Local $bNegative = _IsFractionNegative($aFraction) If @error Then Return SetError(1) If $bNegative And Mod($aRoot[0], 2) = 0 Then Return SetError(5) Local $iSign = ($bNegative And Mod($aRoot[1], 2) <> 0) ? -1 : 1 $aFraction = _FractionAbs($aFraction) Local $iExtended, $iRoot = __WholeNumberDivision($aRoot[0], $aRoot[1]) If @extended Then $iExtended = 1 Local $iDividend If $iExtended Then $iDividend = $aFraction[0] ^ (1 / $iRoot) Else $iDividend = _Root64($aFraction[0], $iRoot) If @extended Then $iExtended = 1 EndIf Local $iDivisor If $iExtended Then $iDivisor = $aFraction[1] ^ (1 / $iRoot) Else $iDivisor = _Root64($aFraction[1], $iRoot) If @extended Then $iExtended = 1 EndIf $aRoot = _Fraction($iSign * $iDividend, $iDivisor) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aRoot) EndFunc ;==> FractionRoot ; #FUNCTION# =================================================================================================================== ; Name...........: _FractionSubtract ; Description ...: Subtracts the second fraction from the first. ; Syntax.........: _FractionSubtract($aFraction1, $aFraction2) ; Parameters.....; $aFraction1 - The first two element array containing a dividend and a divisor. ; $aFraction2 - The second two element array containing a dividend and a divisor (subtracted from $aFraction1). ; Return values .: Success - Returns a two element array containing the resulting fraction. ; Sets @Extended to 1 if rounding or approximation occurs. ; Failure sets @error as follows ; |@error = 1 Invalid input. ; |@error = 2 The divisor cannot become zero. ; |@error = 3 Out of range. ; Author ........: czardas ; ============================================================================================================================== Func _FractionSubtract($aFraction1, $aFraction2) If Not (_IsFraction($aFraction1) And _IsFraction($aFraction2)) Then Return SetError(1) Local $iValue_1, $iValue_2, $iDividend, $iDivisor, $iExtended = 0 If __OverflowDetect('*', $aFraction1[0], $aFraction2[1], $iValue_1) Then $iExtended = 1 If __OverflowDetect('*', $aFraction1[1], $aFraction2[0], $iValue_2) Then $iExtended = 1 If __OverflowDetect('-', $iValue_1, $iValue_2, $iDividend) Then $iExtended = 1 If __OverflowDetect('*', $aFraction1[1], $aFraction2[1], $iDivisor) Then $iExtended = 1 Local $aSubtraction = _Fraction($iDividend, $iDivisor) If @extended Then $iExtended = 1 Return SetError(@error, $iExtended, $aSubtraction) EndFunc ;==> _FractionSubtract ; #FUNCTION# =================================================================================================================== ; Name...........: _IsFraction ; Description ...: Checks if the input is an array containing two valid integers ==> representing dividend and divisor. ; Syntax.........: _IsFraction($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Returns True if the input matches the criteria, otherwise returns False. ; Author.........: czardas ; Comments ......; Sets @extended to 1 if the fraction is negative. ; ============================================================================================================================== Func _IsFraction($aFraction) If Not IsArray($aFraction) Then Return False If Ubound($aFraction,0) <> 1 Or Ubound($aFraction) <> 2 Then Return False If Not StringInStr(VarGetType($aFraction[0]), 'Int') Or $aFraction[0] = 0x8000000000000000 Then Return False If Not StringInStr(VarGetType($aFraction[1]), 'Int') Or $aFraction[1] = 0x8000000000000000 Then Return False Return SetExtended((($aFraction[0] < 0 And $aFraction[1] > 0) Or ($aFraction[0] >= 0 And $aFraction[1] < 0)) ? 1 : 0, True) EndFunc ;==> _IsFraction ; #FUNCTION# =================================================================================================================== ; Name...........: _IsFractionNegative ; Description ...: Checks if the input array is a negative fraction. ; Syntax.........: _IsFractionNegative($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Returns True if the dividend and the divisor are of the opposite sign, othewise returns False. ; Failure sets @error to 1 if the input is not a valid array containing a dividend and a divisor. ; Author.........: czardas ; ============================================================================================================================== Func _IsFractionNegative($aFraction) Local $bNegative, $bIsFraction = _IsFraction($aFraction) $bNegative = @extended Return SetError(1 - $bIsFraction, 0, ($bNegative = 1)) EndFunc ;==> _IsFractionNegative ; #FUNCTION# =================================================================================================================== ; Name...........: _Reciprocal ; Description ...: Inverts a fraction by swapping the dividend and the divisor. ; Syntax.........: _Reciprocal($aFraction) ; Parameters.....; $aFraction - A two element array containing a dividend and a divisor. ; Return values .: Returns the reciprocal of the fraction. ; Failure sets @error as follows ; |@error = 1 The input is not a valid array containing a dividend and a divisor. ; |@error = 2 The divisor cannot become zero. ; Author.........: czardas ; ============================================================================================================================== Func _Reciprocal($aFraction) If Not _IsFraction($aFraction) Then Return SetError(1) Local $iDivisor = $aFraction[0] If $iDivisor = 0 Then Return SetError(2) $aFraction[0] = $aFraction[1] $aFraction[1] = $iDivisor Return $aFraction EndFunc ;==> _Reciprocal ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __FloatRatio ; Description ...: Helper function for Fraction() - preprocessing of float parameters to generate two proportional integers. ; Syntax.........: __FloatRatio([ByRef] $nDividend, [ByRef] $nDivisor) ; Parameters.....; $iDividend - Top fractional part ; $iDivisor - Lower fractional part ; Return values .: Success - Integer values are returned ByRef. ; Failure sets @error as follows ; |@error = 1 Out of bounds. ; Author ........: czardas ; Comments ......; No attempt has been made to accomodate for any double precision limitations. ; Small innacuracies can affect the 17th and (sometimes) the 16th digit in double precision. ; Using floats can easily be avoided by only passing integers to the function _Fraction(). ; Input positive floats only ; ============================================================================================================================== Func __FloatRatio(ByRef $nDividend, ByRef $nDivisor) If $nDivisor < 0 Then $nDividend *= -1 $nDivisor *= -1 EndIf If $nDivisor <> 1 Then $nDividend /= $nDivisor Local $nSignificand, $iExponent, $iDigits = 16 ; might as well grab as many digits as are available $nSignificand = __FloatToDigits($nDividend, $iDigits) $iExponent = @extended $nSignificand = Number($nSignificand, 2) ; Int-64 While $iExponent < - 18 ; divide the significand by powers of 10 $iDigits -= 1 If $iDigits < 0 Then ; too small If $nDividend < 1 / (2 * 10 ^ 18) Then ; round down to 0 / 1 $nSignificand = 0 $iExponent = 0 Else ; round up to 1 / 1000000000000000000 $nSignificand = 1 $iExponent = 18 EndIf ExitLoop EndIf $nSignificand = __FloatToDigits($nDividend, $iDigits) $iExponent = @extended ; adjust the exponent to accomodate division of the significand $nSignificand = Number($nSignificand, 2) ; Int-64 WEnd While $iExponent > 0 ; multiply the significand by powers of 10 If __OverflowDetect('*', $nSignificand, 10, $nSignificand) Then Return SetError(1) ; too large ~ out of bounds $iExponent -= 1 ; adjust the exponent to accomodate multiplication of the significand If $iExponent = 0 Then ExitLoop WEnd $nDividend = $nSignificand ; range 0 to 1000000000000000000 $nDivisor = _Power64(10, Abs($iExponent)) ; range 10 ^ (0 to 18) ==> powers of 10 only EndFunc ;==> __FloatRatio ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __FloatToDigits ; Description ...: Extracts a specified number of digits from a float. ; Syntax.........: __FloatToDigits($fFloat, $iDigits) ; Parameters.....; $fFloat - The float to extract the digits from. ; $iDigits - The number of digits to extract after the floating point (exponential representation). ; Return values .: Success - Returns a 32-bit or 64-bit signed integer. ; Sets @extended to the decimal exponent. ==> $fFloat = return value * 10 ^ exponent ; Failure sets @error to 1 if the input is not a float or undefined. ; Author ........: czardas ; ============================================================================================================================== Func __FloatToDigits($fFloat, $iDigits = 14) If VarGetType($fFloat) <> 'Double' Or StringInStr($fFloat, '#') Then Return SetError(1) Local $iSign = ($fFloat < 0) ? -1 : 1 ; machine epsilon = 5 × 10^-15, so the final two digits (16 and 17) could be highly innacurate $fFloat = StringFormat('%.' & $iDigits & 'e', $fFloat) ; rounds to the specified number of decimal places Local $aFloat = StringSplit($fFloat, "e", 2) ; zero-based array If $iSign < 0 Then $aFloat[0] = StringTrimLeft($aFloat[0], 1) ; remove the minus sign ; remove the decimal point and trailing zeros $aFloat[0] = StringLeft($aFloat[0], 1) & StringRegExpReplace(StringRight($aFloat[0], $iDigits), '(0+\z)', '') $aFloat[1] += 1 - StringLen($aFloat[0]) ; adjust the exponent to accommodate changes Return SetExtended($aFloat[1], Int($aFloat[0]) * $iSign) ; add back the minus sign EndFunc ;==> __FloatToDigits ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __GCD ; Description ...: Calculates the greatest common divisor of two integers. Original function name ==> _Greatest_Common_Factor() ; Syntax.........: __GCD($iValue1, $iValue2) ; Parameters.....; $iValue1 - First Integer. ; $iValue2 - Second Integer. ; Return values .: Success - Returns the greatest common divisor of $iValue1 and $iValue2. ; Author.........: Pheonix XL ; Modified.......; czardas ; Comments ......; IMPORTANT - Error checks have been removed. You must run the checks if you use this function yourself. ; ============================================================================================================================== Func __GCD($iValue1, $iValue2) ; Only accepts positive integers greater than zero. ; If Not (IsInt($iValue1) And IsInt($iValue2)) Or $iValue1 < 1 Or $iValue2 < 1 Then Return SetError(1) Local $iToggle If $iValue1 < $iValue2 Then ; Switch values. $iToggle = $iValue1 $iValue1 = $iValue2 $iValue2 = $iToggle EndIf Local $iModulus While 1 ; Method of Euclid. $iModulus = Mod($iValue1, $iValue2) If $iModulus = 0 Then ExitLoop $iValue1 = $iValue2 $iValue2 = $iModulus WEnd Return $iValue2 EndFunc ;==> __GCD ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __Quotient ; Description ...: Returns the quotient after division ~(the whole number part of a fraction). ; Syntax.........: __Quotient($nDividend, $nDivisor) ; Parameters.....; $iDividend - The integer to divide ; $iDivisor - The integer to divide by ; Return values .: Returns the quotient. ; Author ........: czardas ; Comments ......; Uses the same correction method as __WholeNumberDivision() in operator64.au3. ; ============================================================================================================================== Func __Quotient($nDividend, $nDivisor) Local $iQuotient = Floor($nDividend / $nDivisor), $iDifference, $iIntegral While $iQuotient * $nDivisor > $nDividend ; division is overstated $iDifference = ($nDivisor * $iQuotient) - $nDividend $iIntegral = Floor($iDifference / $nDivisor) ; avoid shooting beyond the target If $iIntegral = 0 Then $iIntegral = 1 ; prevents hanging in an infinite loop $iQuotient -= $iIntegral WEnd While $iQuotient * $nDivisor < $nDividend ; division is understated $iDifference = $nDividend - ($nDivisor * $iQuotient) $iIntegral = Floor($iDifference / $nDivisor) ; as above If $iIntegral = 0 Then ExitLoop ; we have found the floor already $iQuotient += $iIntegral WEnd Return $iQuotient EndFunc ;==> __Quotient ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __Simplify ; Description ...: Simplification by division. ; Syntax.........: __Simplify($iDividend, $iDivisor) ; Parameters.....; $iDividend - Top fractional part. ; $iDivisor - Lower fractional part. ; Author ........: czardas ; ============================================================================================================================== Func __Simplify(ByRef $iDividend, ByRef $iDivisor) Local $iGCD = __GCD($iDividend, $iDivisor) If $iGCD > 1 Then $iDividend = __WholeNumberDivision($iDividend, $iGCD) $iDivisor = __WholeNumberDivision($iDivisor, $iGCD) EndIf EndFunc ;==> __SimplifyExamples - currently testing for accuracy and possible bugs. #include 'Fraction.au3' Local $aFraction = _Fraction(3.1416) If @error Then Exit ; ==> Error handling. ConsoleWrite("3.1416 = " & $aFraction[0] & " / " & $aFraction[1] & @LF) $aFraction = _Fraction(0.125 , 2) ConsoleWrite("0.125 / 2 = " & $aFraction[0] & " / " & $aFraction[1] & @LF) $aFraction = _Fraction(0.00125, -0.32) ConsoleWrite("0.00125 / -0.32 = " & $aFraction[0] & " / " & $aFraction[1] & @LF) $aFraction = _Fraction(86418753, 2977963408767) ConsoleWrite("86418753 / 2977963408767 = " & $aFraction[0] & " / " & $aFraction[1] & @LF) ; Multiply two fractions (27 / 28 x 374 / 555) using whole number arithmetic: Local $aProduct = _FractionMultiply(_Fraction(27, 28), _Fraction(374, 555)) ConsoleWrite("27 / 28 x 374 / 555 = " & $aProduct[0] & " / " & $aProduct[1] & @LF) ; The modulus of two fractions: Local $aMod = _FractionMod(_Fraction(-1, 2), _Fraction(1, 3)) ConsoleWrite("Mod(-1/2, 1/3) = " & $aMod[0] & "/" & $aMod[1] & @LF) ; Represent pi (as accurately as possible) using a fraction with denominator of no more than thirteen digits. Local $aPi = _FractionApproximate(_Fraction(3.14159265358979), 1e+013 -1) ConsoleWrite($aPi[0] & " / " & $aPi[1] & " = " & $aPi[0] / $aPi[1] & " ~ Pi" & @LF) Local $aR2 = _FractionApproximate(_Fraction(2^.5), 1.0e+13 -1) ConsoleWrite($aR2[0] & " / " & $aR2[1] & " = " & $aR2[0] / $aR2[1] & " ~ 2^(1/2)" & @LF) Local $aLarge = _Fraction(1.23456789e+017,100000000000000100) If @error Then MsgBox(0, "", @error) ConsoleWrite(@extended & @LF) ConsoleWrite($aLarge[0] & " / " & $aLarge[1] & " = " & $aLarge[0] / $aLarge[1] & " = " & 1.23456789e+017 / 100000000000001000 & @LF) Local $aSmall = _Fraction(1.23456789e-200,8.64197523e-192) If @error Then MsgBox(0, "", @error) ConsoleWrite(@extended & @LF) ConsoleWrite($aSmall[0] & " / " & $aSmall[1] & " = " & $aSmall[0] / $aSmall[1] & " = " & 1.23456789e-200 / 8.64197523e-192 & @LF) Local $aTooSmall = _Fraction(1.23456789e-200,100000000000000100) If @error Then MsgBox(0, "", @error) ConsoleWrite("@extended = " & @extended & @LF) ConsoleWrite($aTooSmall[0] & " / " & $aTooSmall[1] & " = " & $aTooSmall[0] / $aTooSmall[1] & " = " & 1.23456789e-200 / 100000000000001000 & @LF) Local $aTooLarge = _Fraction(100000000000000100, 1.23456789e-200) ConsoleWrite("@error = " & @error & @LF) Local $aAddApprox = _FractionAdd(_Fraction(134567890000, 999999999999), _Fraction(987654321000, 777777777777777)) ConsoleWrite("@extended = " & @extended & @LF) ConsoleWrite($aAddApprox[0] & " / " & $aAddApprox[1] & " = " & $aAddApprox[0] / $aAddApprox[1] & " = " & (134567890000/999999999999 + 987654321000/777777777777777) ; See post 33 for information on the latest update.
    3 points
  2. This project has been discontinued! Here a small tool I wrote to update my Sysinternal tools collection without the need to download always the whole package or visiting the site to check for updates. I know that there are several tools available (also some tools written in AutoIt) but here another one for the collection. It was good exercise for me to code it. Some files from the live web site cannot be downloaded although they are visible! Here the download link of the source code only: AutoIt Sysinternal Tools Synchronizer v0.99.6 build 2020-09-23 beta.7z (1557 downloads previously) -=> Requires AutoIt version 3.3.13.20 or higher / tested on Win8.1 real machine and some VMs: Win7 / Vista / Win10 Compiled exe only: @MediaFire Just select the Sysinternal Tools folder or create one and press the synchronize button to download the selected items. Click on AutoIt label (near to left upper corner) to open menu. Special thanks to LarsJ, Melba23 and mesale0077 for their help. I've still some ideas to implement which are more gimmick related, so it is not finished yet... If you want to add your language please check out #Region Language. Thanks. Please report any bug or if you have any suggestions. The language of the tool tip from each of the executable in the left list view were automatically created using Google translator and weren't checked for correctness. Br, UEZ
    2 points
  3. Problem: well, you know how when your total path length exceeds 256 characters, bad things start to happen, right? Solution: somewhere in the Developer Chat forum, i suggested that long paths should be supported natively by AutoIt. this is progressing leisurely, and until completed, i re-wrote most of AutoIt core file management functions to support long paths. the concept is to call the unicode versions of the file management functions in kernel32.dll, and use the unicode prefix \\?\ or \\?\UNC\ where needed. in addition it requires some preparation steps, like creating directory structure, listing files to support wildcards, etc. this UDF was created because i needed a convenient way to make my existing scripts support long paths. so basically, the use of every LFN function is identical to the use of its native equivalent (same parameters and return values). for example, use _LFN_DirCreate() instead of DirCreate(). that's it. it works exactly the same, except when it comes to too long paths; it this case the LFN functions work where the native AutoIt functions fail. Note #1: you do not need to specify the unicode prefix. the UDF functions take care of that. this works: _LFN_DirCreate("C:\some\ridiculously\long\path\over\260\characters") you don't need this: _LFN_DirCreate("\\?\C:\some\ridiculously\long\path\over\260\characters") Note #2: _LFN_FileCopy lost its unique flags, and is now utilizing the native function FileCopy. Demonstration: hereunder, as well as the UDF, is a demo script of all of this UDF main functions. download the UDF itself (name it "LFN.au3") and the demo script to the same folder, and run the script. note that after each command the script pauses with a MsgBox, so you can review the results of the operation. do feel free to extend the demo script with more flags combinations. it creates long paths in C:\TEMP\LFN, so it won't be too hard to cleanup later once you are done with your tests. tested on file systems: fixed NTFS, removable NTFS, network ext4 Status: testing phase is complete. this UDF is now in production. enjoy! Latest Updates (release notes): post #39 - UDF v5.2 and demo script post #38 - script converter the script converter is GUI-based, with a clear display of the conversion: original/converted lines displayed side-by-side, tooltip to show the context of the converted lines showing 10 lines before and after: also the icon for the LFN conversion script, if you wish to compile: LFN_Script_Converter_NG.ico hope you appreciate the icon design : Downloads: the UDF: #include-Once ; #INDEX# ======================================================================================================================= ; Title .........: LFN ; AutoIt Version : 3.3.14.2 ; UDF Version ...: 5.2 ; Status ........: Production ; Language ......: English ; Description ...: Standard file management functions rewritten to overcome the MAX_PATH limitation of 256 characters by: ; - prepending the unicode prefix \\?\ or \\?\UNC\ where needed ; - calling kernel32 DLL with the unicode versions of the relevant functions ; - validating directory structure before calling the DLL ; - applying wildcards where not supported by the DLL ; - full compliance of parameters and return values with the equivalent native AutoIt functions: ; -- there may be additional use of @extended or @error when required ; -- there may be additional values that existing parameters can accept ; This UDF was created because: ; - not all of the above conditions are met by the WinAPIEx UDF ; - there was a need for convenient way to make existing scripts support long file names ; Native AutoIt functions that did not find their place in this UDF: ; FileChangeDir - couldn't get it to work. ; FileCreateNTFSLink - not sure what it is and what it does. ; FileCreateShortcut - couldn't get it to work. ; FileGetShortcut - couldn't get FileCreateShortcut to work, so didn't proceed here. ; FileInstall - couldn't get it to work. ; FileOpenDialog - couldn't get it to work with init dir in too long path; but it does set @WorkingDir! ; FileRecycle - not applicable: too long paths can not be put to recycle bin anyway. ; FileRecycleEmpty - not applicable: too long paths can not be put to recycle bin anyway. ; FileSaveDialog - couldn't get it to work with init dir in too long path; but it does set @WorkingDir! ; FileSelectFolder - seems to work as is. ; How To use this UDF: ; - for new scripts: as usual, include this UDF in your script and use its functions. ; - for existing scripts: use the conversion script (downloadable from the AutoIt forum). The conversion will ; replace the native functions calls with their LFN equivalents, and add an #include statement for this UDF ; just after your last #include statement (or at the top of your script if you have no #include statements). ; There is no need to change anything in the parameters or return values. ; Remark on the _LFN_Ini* functions: ; - comments (any text following a semicolon) are preserved. Comment following a Key=Value line are considered ; as part of the value string. ; Dll ...........: kernel32.dll ; Author(s) .....: orbs ; Resources .....: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx ; http://www.geoffchappell.com/studies/windows/win32/kernel32/api/ ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;_LFN_DirCopy ;_LFN_DirCreate ;_LFN_DirGetSize ;_LFN_DirMove ;_LFN_DirRemove ;_LFN_FileClose ;_LFN_FileCopy ;_LFN_FileDelete ;_LFN_FileExists ;_LFN_FileFindFirstFile ;_LFN_FileFindNextFile ;_LFN_FileFlush ;_LFN_FileGetAttrib ;_LFN_FileGetEncoding ;_LFN_FileGetLongName ;_LFN_FileGetPos ;_LFN_FileGetShortName ;_LFN_FileGetSize ;_LFN_FileGetTime ;_LFN_FileGetVersion ;_LFN_FileMove ;_LFN_FileOpen ;_LFN_FileRead ;_LFN_FileReadLine ;_LFN_FileReadToArray ;_LFN_FileSetAttrib ;_LFN_FileSetEnd ;_LFN_FileSetPos ;_LFN_FileSetTime ;_LFN_FileWrite ;_LFN_FileWriteLine ;_LFN_IniDelete ;_LFN_IniRead ;_LFN_IniReadSection ;_LFN_IniReadSectionNames ;_LFN_IniRenameSection ;_LFN_IniWrite ;_LFN_IniWriteSection ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirCopy ; Description ...: Copies a directory and all sub-directories and files. ; Syntax.........: _LFN_DirCopy($sSrcPath, $sDstPath[, $iFlag = 0]) ; Parameters ....: $sSrcPath - Path of the source directory (with no trailing backslash). e.g. "C:\Path1" ; $sDstPath - Path of the destination directory (with no trailing backslash). e.g. "C:\Path_Copy" ; $iFlag - [optional] This flag determines whether to overwrite files if they already exist: ; $FC_NOOVERWRITE (0) = (default) do not overwrite existing files ; $FC_OVERWRITE (1) = overwrite existing files ; Constants are defined in FileConstants.au3 ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the destination directory structure doesn't exist, it will be created (if possible). This means that flag 8 ; is assumed, and needs not be specified. ; Overwrite is determined per file, and complies with flag combination. ; NOTE: DirCopy('D:\dir','C:\') will fail, but _LFN_DirCopy('D:\dir','C:\') will succeed. Make of it whatever ; suits you. ; Related .......: ; Dependencies ..: _LFN_DirCreate, _LFN_FileCopy ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_DirCopy($sSrcPath, $sDstPath, $iFlag = 0) ; preparation $sSrcPath = __LFN_Target_RemoveTrailingBackslash($sSrcPath) $sDstPath = __LFN_Target_RemoveTrailingBackslash($sDstPath) If Not __LFN_Target_IsExistingFolder($sSrcPath) Then Return SetError(1, 0, 0) _LFN_DirCreate($sDstPath) ; main action Local $aFiles = __LFN_FilesListToArray($sSrcPath & '\*') Local $i Local $bOneFail = False For $i = 1 To $aFiles[0] If StringRight($aFiles[$i], 1) = '\' Then _LFN_DirCreate($sDstPath & '\' & __LFN_Target_LastElement_Get(StringTrimRight($aFiles[$i], 1))) If Not _LFN_DirCopy($aFiles[$i], $sDstPath & '\' & __LFN_Target_LastElement_Get(StringTrimRight($aFiles[$i], 1)), $iFlag) Then $bOneFail = True Else If Not _LFN_FileCopy($aFiles[$i], $sDstPath & '\', BitOR($iFlag, 8)) Then $bOneFail = True EndIf Next If $bOneFail Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_DirCopy ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirCreate ; Description ...: Creates a directory. ; Syntax.........: _LFN_DirCreate($sPath) ; Parameters ....: $sPath - Full path of the directory to create. ; Return values .: Success - Returns 1 ; Failure - Returns 0, sets @error to 1, and sets @extended to the @error returned from DllCall ; Author ........: orbs ; Modified ......: ; Remarks .......: This function will also create all parent directories given in $sPath if they do not already exist. ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirCreate($sPath) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) Local $nFirstElement = 7 ; assuming local drive Local $nNthFound = 0 Local $i $sPath = __LFN_Target_SetUnicodePrefix($sPath) If @extended = 2 Then ; assumption incorrect, it's a UNC path $nFirstElement = 0 For $i = 1 To StringLen($sPath) If StringMid($sPath, $i, 1) = '\' Then $nNthFound += 1 If $nNthFound = 6 Then $nFirstElement = $i EndIf Next EndIf ; main action For $i = $nFirstElement To StringLen($sPath) If StringMid($sPath, $i, 1) = '\' Then DllCall($hDLL, 'bool', 'CreateDirectoryW', 'wstr', StringLeft($sPath, $i), 'struct*', 0) EndIf Next DllCall($hDLL, 'bool', 'CreateDirectoryW', 'wstr', $sPath, 'struct*', 0) If __LFN_Target_IsExistingFolder($sPath) Then Return 1 Return 0 EndFunc ;==>_LFN_DirCreate ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirGetSize ; Description ...: Use exactly like the native AutoIt function DirGetSize ; Syntax.........: _LFN_DirGetSize($sPath[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_DirGetSize($sPath, $iFlag = 0) $sPath = __LFN_Target_SetUnicodePrefix($sPath) Local $result = DirGetSize($sPath, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_DirGetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirMove ; Description ...: Moves a directory and all sub-directories and files. ; Syntax.........: _LFN_DirMove($sSrcPath, $sDstPath[, $iFlag = 0]) ; Parameters ....: $sSrcPath - Path of the source directory (with no trailing backslash). e.g. "C:\Path1" ; $sDstPath - Path of the destination directory (with no trailing backslash). e.g. "C:\Path_Copy" ; $iFlag - [optional] This flag determines whether to overwrite files if they already exist: ; $FC_NOOVERWRITE (0) = (default) do not overwrite existing files ; $FC_OVERWRITE (1) = overwrite existing files ; Constants are defined in FileConstants.au3 ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: - If the source and destination are on different volumes or UNC paths are used, then a copy+delete operation ; is performed rather than a move. If the 'copy' or 'delete' fails, then depending on the reason of failure, ; there may remain some files either in the source or destination, where not expected. ; - If the destination already exists and the overwrite flag IS specified, then the source directory will be ; moved inside the destination. If a subfolder of the destination folder already exists by the name of the ; source folder, then source files will overwrite destination files if exist. ; - If the destination already exists and the overwrite flag IS NOT specified, the operation fails. ; - Because AutoIt lacks a "_LFN_DirRename" function, use _LFN_DirMove to rename a folder! ; Related .......: ; Dependencies ..: _LFN_FileDelete, _LFN_DirCopy, _LFN_DirRemove ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirMove($sSrcPath, $sDstPath, $iFlag = 0) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation $sSrcPath = __LFN_Target_RemoveTrailingBackslash($sSrcPath) $sDstPath = __LFN_Target_RemoveTrailingBackslash($sDstPath) If Not __LFN_Target_IsExistingFolder($sSrcPath) Then Return SetError(1, 0, 0) If __LFN_FilesExist($sDstPath) Then Switch @extended Case 1 ; file If $iFlag Then ; overwrite => delete file _LFN_FileDelete($sSrcPath) Else Return SetError(1, 0, 0) ; fail EndIf Case 3 ; folder If $iFlag Then ; overwrite => move inside $sDstPath = $sDstPath & '\' & __LFN_Target_LastElement_Get($sSrcPath) Else Return SetError(1, 0, 0) ; fail EndIf EndSwitch EndIf ; main action Local $aRet = DllCall($hDLL, 'bool', 'MoveFileExW', 'wstr', __LFN_Target_SetUnicodePrefix($sSrcPath), 'wstr', __LFN_Target_SetUnicodePrefix($sDstPath), 'dword', 2 + $iFlag) If $aRet[0] = 0 Then If _LFN_DirCopy($sSrcPath, $sDstPath, $iFlag) Then _LFN_DirRemove($sSrcPath, 3) Else Return SetError(1, 0, 0) EndIf EndIf Return 1 EndFunc ;==>_LFN_DirMove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_DirRemove ; Description ...: Deletes a directory. ; Syntax.........: _LFN_DirRemove($sPath[, $iFlag = 0]) ; Parameters ....: $sPath - Full path of the directory to remove. ; $iFlag - [optional] This flag is a combination of the following values: ; 1 = recurse subfolders ; 2 = clear the Read-only and System attributes to force removal ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: _LFN_FileSetAttrib, _LFN_FileDelete ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_DirRemove($sPath, $iFlag = 0) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) $sPath = __LFN_Target_SetUnicodePrefix($sPath) If Not __LFN_Target_IsExistingFolder($sPath) Then Return SetError(1, 0, 0) ; main action If BitAND($iFlag, 1) Then Local $aFiles = __LFN_FilesListToArray($sPath, BitAND($iFlag, 1)) Local $i, $aRet For $i = $aFiles[0] To 1 Step -1 If StringRight($aFiles[$i], 1) = '\' Then If BitAND($iFlag, 2) Then _LFN_FileSetAttrib($aFiles[$i], '-RS') $aRet = DllCall($hDLL, 'bool', 'RemoveDirectoryW', 'wstr', StringTrimRight($aFiles[$i], 1)) If $aRet[0] = 0 Then Return SetError(1, @error, 0) Else If BitAND($iFlag, 2) Then _LFN_FileSetAttrib($aFiles[$i], '-RS') _LFN_FileDelete($aFiles[$i]) EndIf Next EndIf $aRet = DllCall($hDLL, 'bool', 'RemoveDirectoryW', 'wstr', $sPath) If @error Then Return SetError(1, @error, 0) If FileExists($sPath) Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_DirRemove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileClose ; Description ...: Use exactly like the native AutoIt function FileClose ; Syntax.........: _LFN_FileClose($hFile) ; =============================================================================================================================== Func _LFN_FileClose($hFile) Local $result = FileClose($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileClose ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileCopy ; Description ...: Use exactly like the native AutoIt function FileCopy ; Syntax ........: _LFN_FileCopy($sSrc, $sDst[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileCopy($sSrc, $sDst, $iFlag = 0) $sSrc = __LFN_Target_SetUnicodePrefix($sSrc) $sDst = __LFN_Target_SetUnicodePrefix($sDst) Local $result = FileCopy($sSrc, $sDst, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileCopy ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileDelete ; Description ...: Use exactly like the native AutoIt function FileDelete ; Syntax.........: _LFN_FileDelete($sMask) ; =============================================================================================================================== Func _LFN_FileDelete($sMask) $sMask = __LFN_Target_SetUnicodePrefix($sMask) Local $result = FileDelete($sMask) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileDelete ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileExists ; Description ...: Use exactly like the native AutoIt function FileExists ; Syntax.........: _LFN_FileExists($sFile) ; =============================================================================================================================== Func _LFN_FileExists($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileExists($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileExists ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFindFirstFile ; Description ...: Use exactly like the native AutoIt function FileFindFirstFile ; Syntax.........: _LFN_FileFindFirstFile($sFile) ; =============================================================================================================================== Func _LFN_FileFindFirstFile($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileFindFirstFile($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFindFirstFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFindNextFile ; Description ...: Use exactly like the native AutoIt function FileFindNextFile ; Syntax.........: _LFN_FileFindNextFile($hSearch) ; =============================================================================================================================== Func _LFN_FileFindNextFile($hSearch) Local $result = FileFindNextFile($hSearch) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFindNextFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileFlush ; Description ...: Use exactly like the native AutoIt function FileFlush ; Syntax.........: _LFN_FileFlush($hFile) ; =============================================================================================================================== Func _LFN_FileFlush($hFile) Local $result = FileFlush($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileFlush ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetAttrib ; Description ...: Use exactly like the native AutoIt function FileGetAttrib ; Syntax.........: _LFN_FileGetAttrib($sTarget) ; =============================================================================================================================== Func _LFN_FileGetAttrib($sTarget) $sTarget = __LFN_Target_SetUnicodePrefix($sTarget) Local $result = FileGetAttrib($sTarget) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetAttrib ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetEncoding ; Description ...: Use exactly like the native AutoIt function FileGetEncoding ; Syntax.........: _LFN_FileGetEncoding($xFile[, $nMode = 1]) ; =============================================================================================================================== Func _LFN_FileGetEncoding($xFile, $nMode = 1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileGetEncoding($xFile, $nMode) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetEncoding ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetLongName ; Description ...: Returns the long path+name of the path+name passed. ; Syntax.........: _LFN_FileGetLongName($sFile[, $iFlag = 0]) ; Parameters ....: $sFile - Full path and file name to convert ; $iFlag - [optional] if 1 file can have relative dir, e.g. "..\file.txt" ; Return values .: Success - Returns the long path+name of the path+name passed. ; Failure - Returns the parameter and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx ; http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963(v=vs.85).aspx ; Example .......: No ; =============================================================================================================================== Func _LFN_FileGetLongName($sFile, $iFlag = 0) Local $aRet Local $sFileFullPath If $iFlag Then $aRet = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', __LFN_Target_SetUnicodePrefix($sFile), 'dword', 4096, 'wstr', '', 'ptr', 0) If @error Or Not $aRet[0] Then $sFileFullPath = $sFile $sFileFullPath = $aRet[3] Else $sFileFullPath = $sFile EndIf $aRet = DllCall('kernel32.dll', 'dword', 'GetLongPathNameW', _ 'wstr', __LFN_Target_SetUnicodePrefix($sFileFullPath), _ 'wstr', '', _ 'dword', 65536) If $aRet[0] = 0 Then Return SetError(1, $sFile) Return __LFN_Target_UnSetUnicodePrefix($aRet[2]) EndFunc ;==>_LFN_FileGetLongName ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetPos ; Description ...: Use exactly like the native AutoIt function FileGetPos ; Syntax.........: _LFN_FileGetPos($hFile) ; =============================================================================================================================== Func _LFN_FileGetPos($hFile) Local $result = FileGetPos($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetPos ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetSize ; Description ...: Use exactly like the native AutoIt function FileGetSize ; Syntax.........: _LFN_FileGetSize($sFile) ; =============================================================================================================================== Func _LFN_FileGetSize($sFile) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetSize($sFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetShortName ; Description ...: Use exactly like the native AutoIt function FileGetShortName ; Syntax.........: _LFN_FileGetShortName($sFile[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileGetShortName($sFile, $iFlag = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetShortName($sFile, $iFlag) Local $nError = @error Local $nExtended = @extended $result = __LFN_Target_UnSetUnicodePrefix($result) ; the result is a short name, therefore must not have the unicode prefix. Return SetError($nError, $nExtended, $result) EndFunc ;==>_LFN_FileGetShortName ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetTime ; Description ...: Use exactly like the native AutoIt function FileGetTime ; Syntax.........: _LFN_FileGetTime($sFile[, $nOption = 0[, $nFormat = 0]]) ; =============================================================================================================================== Func _LFN_FileGetTime($sFile, $nOption = 0, $nFormat = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileGetTime($sFile, $nOption, $nFormat) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileGetTime ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileGetVersion ; Description ...: Use exactly like the native AutoIt function FileGetVersion ; Syntax.........: _LFN_FileGetVersion($sFile[, $sField = -1]) ; =============================================================================================================================== Func _LFN_FileGetVersion($sFile, $sField = -1) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $sResult If $sField = -1 Then $sResult = FileGetVersion($sFile) Return SetError(@error, @extended, $sResult) Else $sResult = FileGetVersion($sFile, $sField) Return SetError(@error, @extended, $sResult) EndIf EndFunc ;==>_LFN_FileGetVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileMove ; Description ...: Use exactly like the native AutoIt function FileMove ; Syntax ........: _LFN_FileMove($sSrc, $sDst[, $iFlag = 0]) ; =============================================================================================================================== Func _LFN_FileMove($sSrc, $sDst, $iFlag = 0) $sSrc = __LFN_Target_SetUnicodePrefix($sSrc) $sDst = __LFN_Target_SetUnicodePrefix($sDst) Local $result = FileMove($sSrc, $sDst, $iFlag) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileMove ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileOpen ; Description ...: Use exactly like the native AutoIt function FileOpen ; Syntax.........: _LFN_FileOpen($sFile[, $nMode = 0]) ; =============================================================================================================================== Func _LFN_FileOpen($sFile, $nMode = 0) $sFile = __LFN_Target_SetUnicodePrefix($sFile) Local $result = FileOpen($sFile, $nMode) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileOpen ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileRead ; Description ...: Use exactly like the native AutoIt function FileRead ; Syntax.........: _LFN_FileRead($xFile[, $nCount = -1]) ; =============================================================================================================================== Func _LFN_FileRead($xFile, $nCount = -1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result If $nCount < 0 Then $result = FileRead($xFile) Else $result = FileRead($xFile, $nCount) EndIf Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileRead ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileReadLine ; Description ...: Use exactly like the native AutoIt function FileReadLine ; Syntax.........: _LFN_FileReadLine($xFile[, $nLine = 1]) ; =============================================================================================================================== Func _LFN_FileReadLine($xFile, $nLine = 1) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result If $nLine = 1 Then $result = FileReadLine($xFile) Else $result = FileReadLine($xFile, $nLine) EndIf Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileReadLine ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileReadToArray ; Description ...: Use exactly like the native AutoIt function FileReadToArray ; Syntax.........: _LFN_FileReadToArray($xFile) ; =============================================================================================================================== Func _LFN_FileReadToArray($xFile) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileReadToArray($xFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileReadToArray ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetAttrib ; Description ...: Sets or clears attributes of one or more files/directories. ; Syntax.........: _LFN_FileSetAttrib($sTarget, $sAttrib[, $bRecurse = False]) ; Parameters ....: Target - Full path of file(s) to set attributes for (wildcards supported). ; $sAttrib - A string representation of the attributes to set or clear - see Remarks. ; $bRecurse - [optional] Set to True if to recurse subdirectories. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error: ; 1 - Error opening the kernel32 DLL. ; 2 - The attributes parameter includes an invalid attribute - see Remarks. ; 3 - deprecated (used to be "No files found", but this is not an error, but a legitimate result). ; 4 - At least one file could not have its attributes changed. ; Author ........: orbs ; Modified ......: ; Remarks .......: - The attributes that can be modified with the function are + or -: ; "R" = READONLY ; "A" = ARCHIVE ; "S" = SYSTEM ; "H" = HIDDEN ; "N" = NORMAL ; "O" = OFFLINE ; "T" = TEMPORARY ; Related .......: ; Dependencies ..: ; Link ..........: http://msdn.microsoft.com/en-us/library/aa365535(v=vs.85).aspx ; http://msdn.microsoft.com/en-us/library/gg258117(v=vs.85).aspx ; http://stackoverflow.com/questions/12594403/fasm-if-file-exists-using-getfileattributes-invalid-file-attributes-value ; Example .......: No ; =============================================================================================================================== Func _LFN_FileSetAttrib($sTarget, $sAttrib, $bRecurse = False) ; reversion If Not __LFN_Target_IsMask($sTarget) And _ ; target is a single file or folder StringLen($sTarget) < 260 And _ ; target is short Not $bRecurse Then _ ; no recurse (recurse may breach MAX_PATH limit) Return FileSetAttrib($sTarget, $sAttrib, $bRecurse) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation Local Const $_LFN_FILE_ATTRIBUTE_ARCHIVE = 32 ;(0x20) Local Const $_LFN_FILE_ATTRIBUTE_COMPRESSED = 2048 ;(0x800) Local Const $_LFN_FILE_ATTRIBUTE_DEVICE = 64 ;(0x40) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_DIRECTORY = 16 ;(0x10) Local Const $_LFN_FILE_ATTRIBUTE_ENCRYPTED = 16384 ;(0x4000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_HIDDEN = 2 ;(0x2) Local Const $_LFN_FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 ;(0x8000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_NORMAL = 128 ;(0x80) Local Const $_LFN_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 ;(0x2000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 ;(0x20000) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_OFFLINE = 4096 ;(0x1000) Local Const $_LFN_FILE_ATTRIBUTE_READONLY = 1 ;(0x1) Local Const $_LFN_FILE_ATTRIBUTE_REPARSE_POINT = 1024 ;(0x400) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_SPARSE_FILE = 512 ;(0x200) ; not used here Local Const $_LFN_FILE_ATTRIBUTE_SYSTEM = 4 ;(0x4) Local Const $_LFN_FILE_ATTRIBUTE_TEMPORARY = 256 ;(0x100) Local Const $_LFN_FILE_ATTRIBUTE_VIRTUAL = 65536 ;(0x10000) ; not used here Local $aAttributes[18][2] = [[0, 0], _ [$_LFN_FILE_ATTRIBUTE_ARCHIVE, 'A'], _ [$_LFN_FILE_ATTRIBUTE_COMPRESSED, 'C'], _ [$_LFN_FILE_ATTRIBUTE_DEVICE, ''], _ [$_LFN_FILE_ATTRIBUTE_DIRECTORY, 'D'], _ [$_LFN_FILE_ATTRIBUTE_ENCRYPTED, ''], _ [$_LFN_FILE_ATTRIBUTE_HIDDEN, 'H'], _ [$_LFN_FILE_ATTRIBUTE_INTEGRITY_STREAM, ''], _ [$_LFN_FILE_ATTRIBUTE_NORMAL, 'N'], _ [$_LFN_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, ''], _ [$_LFN_FILE_ATTRIBUTE_NO_SCRUB_DATA, ''], _ [$_LFN_FILE_ATTRIBUTE_OFFLINE, 'O'], _ [$_LFN_FILE_ATTRIBUTE_READONLY, 'R'], _ [$_LFN_FILE_ATTRIBUTE_REPARSE_POINT, ''], _ [$_LFN_FILE_ATTRIBUTE_SPARSE_FILE, ''], _ [$_LFN_FILE_ATTRIBUTE_SYSTEM, 'S'], _ [$_LFN_FILE_ATTRIBUTE_TEMPORARY, 'T'], _ [$_LFN_FILE_ATTRIBUTE_VIRTUAL, '']] Local Const $_LFN_INVALID_FILE_ATTRIBUTES = 4294967295 ;(0xFFFFFFFF, also equals -1 for unsigned DWORD) Local $bAttribToSet = True Local $nAttribToSet = 0 Local $nAttribToClear = 0 Local $i, $j For $i = 1 To StringLen($sAttrib) Switch StringUpper(StringMid($sAttrib, $i, 1)) Case '+' $bAttribToSet = True Case '-' $bAttribToSet = False Case 'R', 'A', 'S', 'H', 'N', 'O', 'T' For $j = 1 To UBound($aAttributes) - 1 If $aAttributes[$j][1] = StringUpper(StringMid($sAttrib, $i, 1)) Then If $bAttribToSet Then $nAttribToSet = BitOR($nAttribToSet, $aAttributes[$j][0]) Else $nAttribToClear = BitOR($nAttribToClear, $aAttributes[$j][0]) EndIf EndIf Next Case Else Return SetError(2, 0, 0) EndSwitch Next ; main action Local $aFiles[2] = [1, $sTarget] If Not __LFN_Target_IsExistingFolder($sTarget) Or $bRecurse Then $aFiles = __LFN_FilesListToArray($sTarget, $bRecurse) If __LFN_Target_IsExistingFolder($sTarget) And $bRecurse Then __LFN_ReDim($aFiles, $sTarget & '\') Local $bOneFail = False Local $sOneName = '' Local $aRet, $nAttribToChange For $i = $aFiles[0] To 1 Step -1 $sOneName = $aFiles[$i] If StringRight($sOneName, 1) = '\' Then $sOneName = StringTrimRight($sOneName, 1) $aRet = DllCall($hDLL, 'dword', 'GetFileAttributesW', 'wstr', $sOneName) If @error Or $aRet[0] = $_LFN_INVALID_FILE_ATTRIBUTES Then $bOneFail = True ContinueLoop EndIf $nAttribToChange = $aRet[0] $nAttribToChange = BitOR($nAttribToChange, $nAttribToSet) $nAttribToChange = BitAND($nAttribToChange, BitNOT($nAttribToClear)) If $nAttribToChange = $aRet[0] Then ContinueLoop ; no need to change $aRet = DllCall($hDLL, 'int', 'SetFileAttributesW', 'wstr', $sOneName, 'dword', $nAttribToChange) If @error Or $aRet[0] = 0 Then $bOneFail = True ContinueLoop EndIf Next If $bOneFail Then Return SetError(4, 0, 0) Return 1 EndFunc ;==>_LFN_FileSetAttrib ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetPos ; Description ...: Use exactly like the native AutoIt function FileSetPos ; Syntax.........: _LFN_FileSetPos($hFile, $nOffset, $nOrigin) ; =============================================================================================================================== Func _LFN_FileSetPos($hFile, $nOffset, $nOrigin) Local $result = FileSetPos($hFile, $nOffset, $nOrigin) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileSetPos ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetEnd ; Description ...: Use exactly like the native AutoIt function FileSetEnd ; Syntax.........: _LFN_FileSetEnd($hFile) ; =============================================================================================================================== Func _LFN_FileSetEnd($hFile) Local $result = FileSetEnd($hFile) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileSetEnd ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileSetTime ; Description ...: Sets the timestamp of one of more files. ; Syntax.........: _LFN_FileSetTime($sTarget, $sTimestamp[, $nType = 0[, $bRecurse = False]]) ; Parameters ....: Target - Full path of file(s) to set timestamp for (wildcards supported). ; $sTimestamp - A string which denotes the new time to set. ; format: "YYYYMMDDhhmmss" (Year, Month, Day, hour (24hr clock), minute, second). ; If an empty string is passed, then the current time is used. ; $nType - [optional] Timestamp to change: ; $FT_MODIFIED (0) = Last modified (default) ; $FT_CREATED (1) = Created ; $FT_ACCESSED (2) = Last accessed ; Constants are defined in FileConstants.au3 ; $bRecurse - [optional] Set to True if to recurse subdirectories. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: Using a date earlier than 1980-01-01 will have no effect. ; Trying to change a timestamp on read-only files will result in an error. ; This function fails in the following conditions: ; - Invalid timestamp: string is not all integer or not exactly 14 characters in length ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_FileSetTime($sTarget, $sTimestamp, $nType = 0, $bRecurse = False) ; reversion If Not __LFN_Target_IsMask($sTarget) And _ ; target is a single file or folder StringLen($sTarget) < 260 And _ ; target is short Not $bRecurse Then _ ; no recurse (recurse may breach MAX_PATH limit) Return FileSetTime($sTarget, $sTimestamp, $nType, $bRecurse) ; standard procedure Local $hDLL = __LFN_DllOpen() If @error Then Return SetError(1, 0, 0) ; preparation If Not __LFN_FilesExist($sTarget) Then Return SetError(1, 0, 0) If Not StringIsInt($sTimestamp) Or StringLen($sTimestamp) <> 14 Then Return SetError(1, 0, 0) ; - parse parameter Local $sYYYY = StringLeft($sTimestamp, 4) Local $sMM = StringMid($sTimestamp, 5, 2) Local $sDD = StringMid($sTimestamp, 7, 2) Local $sHH = StringMid($sTimestamp, 9, 2) Local $sMN = StringMid($sTimestamp, 11, 2) Local $sSS = StringMid($sTimestamp, 13, 2) ; - enclode time to "System" time format ; = _Date_Time_EncodeSystemTime Local Const $_LFN_tagSYSTEMTIME = 'struct;word Year;word Month;word Dow;word Day;word Hour;word Minute;word Second;word MSeconds;endstruct' Local $tSystemTime_File = DllStructCreate($_LFN_tagSYSTEMTIME) DllStructSetData($tSystemTime_File, 'Month', Number($sMM)) DllStructSetData($tSystemTime_File, 'Day', Number($sDD)) DllStructSetData($tSystemTime_File, 'Year', Number($sYYYY)) DllStructSetData($tSystemTime_File, 'Hour', Number($sHH)) DllStructSetData($tSystemTime_File, 'Minute', Number($sMN)) DllStructSetData($tSystemTime_File, 'Second', Number($sSS)) DllStructSetData($tSystemTime_File, 'MSeconds', 0) ; - convert "System" time format to "UTC System" time format ; = _Date_Time_TzSpecificLocalTimeToSystemTime Local $aRet Local $tUTC = DllStructCreate($_LFN_tagSYSTEMTIME) $aRet = DllCall("kernel32.dll", "ptr", "TzSpecificLocalTimeToSystemTime", "ptr", 0, "ptr", DllStructGetPtr($tSystemTime_File), "struct*", $tUTC) If @error Then Return SetError(1, 0, 0) ; - convert "System" time format to "File" time format ; = _Date_Time_SystemTimeToFileTime Local Const $_LFN_tagFILETIME = 'struct;dword Lo;dword Hi;endstruct' Local $tFileTime_File = DllStructCreate($_LFN_tagFILETIME) $aRet = DllCall($hDLL, 'bool', 'SystemTimeToFileTime', 'struct*', $tUTC, 'struct*', $tFileTime_File) If @error Then Return SetError(1, 0, 0) ; - decide which timestamp to change Local $pCreated = 0 Local $pAccessed = 0 Local $pModified = 0 Switch $nType Case 1 ; "Created" $pCreated = DllStructGetPtr($tFileTime_File) Case 2 ; "Accessed" $pAccessed = DllStructGetPtr($tFileTime_File) Case Else ; "Modified" $pModified = DllStructGetPtr($tFileTime_File) EndSwitch ; main action Local $aFiles = __LFN_FilesListToArray($sTarget, $bRecurse) If @extended = 0 Then Return SetError(1, 0, 0) ; no files found Local $hFile Local $bOneFail = False For $i = $aFiles[0] To 1 Step -1 If StringRight($aFiles[$i], 1) = '\' Then ContinueLoop ; it's a subfolder ; _WinAPI_CreateFile (does not equal FileOpen!) $aRet = DllCall($hDLL, 'handle', 'CreateFileW', 'wstr', $aFiles[$i], 'dword', 0x40000000, 'dword', 0, 'ptr', 0, 'dword', 3, 'dword', 0, 'ptr', 0) $hFile = $aRet[0] ; finally... $aRet = DllCall($hDLL, 'bool', 'SetFileTime', 'handle', $hFile, 'ptr', $pCreated, 'ptr', $pAccessed, 'ptr', $pModified) If $aRet[0] = 0 Then $bOneFail = True EndIf ;_WinAPI_CloseHandle (does not equal FileClose!) $aRet = DllCall($hDLL, 'bool', 'CloseHandle', 'handle', $hFile) Next If $bOneFail Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_FileSetTime ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileWrite ; Description ...: Use exactly like the native AutoIt function FileWrite ; Syntax.........: _LFN_FileWrite($xFile, $xData) ; =============================================================================================================================== Func _LFN_FileWrite($xFile, $xData) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileWrite($xFile, $xData) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileWrite ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_FileWriteLine ; Description ...: Use exactly like the native AutoIt function FileWriteLine ; Syntax.........: _LFN_FileWriteLine($xFile, $xData) ; =============================================================================================================================== Func _LFN_FileWriteLine($xFile, $xData) If IsString($xFile) Then $xFile = __LFN_Target_SetUnicodePrefix($xFile) Local $result = FileWriteLine($xFile, $xData) Return SetError(@error, @extended, $result) EndFunc ;==>_LFN_FileWriteLine ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniDelete ; Description ...: Deletes a value from a standard format .ini file. ; Syntax.........: _LFN_IniDelete($sFile, $sSection[, $sKey = '']) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - [optional] The key name in the .ini file to delete. If the key name is not given the entire ; section is deleted. The Default keyword may also be used which will cause the section to be deleted. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniDelete($sFile, $sSection, $sKey = '') If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True If $sKey = '' Then $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 EndIf Else If $bSectionFound Then ; entering next section If $sKey = '' Then $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf Else If $bSectionFound And $sKey <> '' Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then $iFirstLineToDelete = $i $iLastLineToDelete = $i EndIf EndIf EndIf Next Local $hFile Local $bError If $iFirstLineToDelete > -1 And $iLastLineToDelete >= $iFirstLineToDelete Then $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) Else Return SetError(1, 0, 0) EndIf Return 1 EndFunc ;==>_LFN_IniDelete ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniRead ; Description ...: Reads a value from a standard format .ini file. ; Syntax.........: _LFN_IniRead($sFile, $sSection, $sKey, $xDefaultValue) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - The key name in the .ini file. ; $xDefaultValue - The default value to return if the requested key is not found. ; Return values .: Success - Returns the requested key value as a string. ; Failure - Returns the default string if the requested key is not found or any error occured. ; Author ........: orbs ; Modified ......: ; Remarks .......: All values returned are converted as a string. ; A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniRead($sFile, $sSection, $sKey, $xDefaultValue) If Not _LFN_FileExists($sFile) Then Return $xDefaultValue Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return $xDefaultValue Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section, key not found Return $xDefaultValue ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then Return StringTrimLeft($aFileLines[$i], $iPos) EndIf EndIf Next Return $xDefaultValue EndFunc ;==>_LFN_IniRead ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniReadSection ; Description ...: Reads all key/value pairs from a section in a standard format .ini file. ; Syntax.........: _LFN_IniReadSection($sFile, $sSection) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; Return values .: Success - Returns a 2-D array where element[n][0] is the key and element[n][1] is the value. ; Failure - Returns 0 and sets the @error flag to non-zero if unable to read the section (The INI file may not ; exist or the section may not exist or is empty). ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; The number of elements returned will be in element[0][0]. If an @error occurs, no array is created. ; This function is not impacted by the 32kB limitation. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniReadSection($sFile, $sSection) If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $aResult[1][2] $aResult[0][0] = 0 Local $bSectionFound = False Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If $iPos = 0 Then ContinueLoop __LFN_ReDim2D($aResult) $aResult[$aResult[0][0]][0] = StringLeft($aFileLines[$i], $iPos - 1) $aResult[$aResult[0][0]][1] = StringTrimLeft($aFileLines[$i], $iPos) EndIf EndIf Next ReDim $aResult[$aResult[0][0] + 1][2] Return $aResult EndFunc ;==>_LFN_IniReadSection ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniReadSectionNames ; Description ...: Reads all sections in a standard format .ini file. ; Syntax.........: _LFN_IniReadSectionNames($sFile) ; Parameters ....: $sFile - The filename of the .ini file. ; Return values .: Success - Returns a 1-D array of all section names in the .ini file. ; Failure - Returns 0 and sets the @error flag to non-zero. ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; The number of elements returned will be in element[0]. If an @error occurs, no array is created. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniReadSectionNames($sFile) If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $aResult[1] = [0] For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then __LFN_ReDim($aResult, StringTrimRight(StringTrimLeft($aFileLines[$i], 1), 1)) Next If $aResult[0] = 0 Then Return SetError(1, 0, 0) ReDim $aResult[$aResult[0] + 1] Return $aResult EndFunc ;==>_LFN_IniReadSectionNames ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniRenameSection ; Description ...: Renames a section in a standard format .ini file. ; Syntax.........: _LFN_IniRenameSection($sFile, $sSection, $sNewSection[, $bOverwrite = False]) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section to be renamed. ; $sNewSection - The new name for the section. ; $bOverwrite - [optional] if a section already exists by the new name, set to True to overwrite it. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to non-zero. ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniRenameSection($sFile, $sSection, $sNewSection, $bOverwrite = False) If $sSection = $sNewSection Then Return 1 If Not _LFN_FileExists($sFile) Then Return SetError(1, 0, 0) Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $bSectionFound = False Local $bNewSectionFound = False Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True If StringLeft($aFileLines[$i], StringLen($sNewSection) + 2) = '[' & $sNewSection & ']' Then $bNewSectionFound = True $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 Else If $bNewSectionFound Then ; entering next section $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf EndIf Next If Not $bSectionFound Then Return SetError(1, 0, 0) If $bNewSectionFound And Not $bOverwrite Then Return SetError(1, 0, 0) Local $hFile Local $bError $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $aFileLines[$i] = StringReplace($aFileLines[$i], $sSection, $sNewSection) _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniRenameSection ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniWrite ; Description ...: Writes a value to a standard format .ini file. ; Syntax.........: _LFN_IniWrite($sFile, $sSection, $sKey, $xValue) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $sKey - The key name in the .ini file. ; $xValue - The value to write/change. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error ro 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; - If the file does not already exist, it is created so long as the directory exists. Keys and/or sections are ; added to the end and are not sorted in any way. ; - If you would like to wrap quotes around an ini value, then you need to double up the quotation marks as the ; first set of quotation marks are stripped. For example: ""This is a test"" will produce "This is a test" ; when using IniRead() or such-like. ; - Leading and trailing whitespace is stripped. In order to preserve the whitespace, the string must be quoted. ; For example, " this is a test" will preserve the whitespace but per above, the quotation marks are stripped. ; - Multi-line values are not possible. ; - If you want to use an ini file with Unicode encoding, first create an .ini file by using the FileOpen() ; function with the mode parameter set to a Unicode parameter. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileWriteLine, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniWrite($sFile, $sSection, $sKey, $xValue) Local $sValue = String($xValue) $sValue = StringStripWS($sValue, 3) If StringLeft($sValue, 1) = '"' And StringRight($sValue, 1) = '"' Then $sValue = StringTrimLeft(StringTrimRight($sValue, 1), 1) If Not _LFN_FileExists($sFile) Then _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then Return SetError(1, 0, 0) _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then Return SetError(1, 0, 0) Return 1 EndIf Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $bToDo = -1 ; 0 = replace existing line, 1 = insert line in existing section, 2 = add new section, 3 = add new line at last section Local $bSectionFound = False Local $iLineToInsert = -1 Local $iPos = 0 For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True Else If $bSectionFound Then ; entering next section, key not found $iLineToInsert = $i $bToDo = 1 ExitLoop EndIf EndIf Else If $bSectionFound Then $iPos = StringInStr($aFileLines[$i], '=') If StringLeft($aFileLines[$i], $iPos - 1) = $sKey Then $aFileLines[$i] = $sKey & '=' & $sValue $bToDo = 0 ExitLoop Else If $i = UBound($aFileLines) - 1 Then $bToDo = 3 EndIf EndIf EndIf Next If Not $bSectionFound Then $bToDo = 2 Local $bError = False Local $hFile Switch $bToDo Case 0 $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) Case 1 While $aFileLines[$iLineToInsert - 1] = '' $iLineToInsert -= 1 WEnd $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i = $iLineToInsert Then _LFN_FileWriteLine($hFile, $sKey & '=' & $sValue) If @error Then $bError = True ExitLoop EndIf EndIf _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) Case 2 _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then $bError = True _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then $bError = True Case 3 _LFN_FileWriteLine($sFile, $sKey & '=' & $sValue) If @error Then $bError = True Case Else $bError = True EndSwitch If $bError Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniWrite ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LFN_IniWriteSection ; Description ...: Writes a section to a standard format .ini file. ; Syntax.........: _LFN_IniWriteSection($sFile, $sSection, $xData[, $iFirstEntry = 1]) ; Parameters ....: $sFile - The filename of the .ini file. ; $sSection - The section name in the .ini file. ; $xData - The data to write. The data can either be a string or an array. If the data is a string, then ; each key=value pair must be delimited by @LF. If the data is an array, the array must be 2-D ; and the second dimension must be 2 elements. ; $iFirstEntry - [optional] If an array is passed as data, this specifies the index to start writing from. ; By default, this is 1 so that the return value of IniReadSection() can be used immediately. ; For manually created arrays, this value may need to be different depending on how the array was ; created. This parameter is ignored if a string is passed as data. ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error ro 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: A standard ini file looks like: ; [SectionName] ; Key=Value ; - _LFN_IniWrite Remarks about doubling quotation marks or quoting whitespace are irrelevant here. Data is ; written to the .ini file as is. ; - If the file does not already exist, it is created so long as the directory exists. Keys and/or sections are ; added to the end and are not sorted in any way. ; - If the section being written already exists, its contents will be overwritten. ; - If you want to use an ini file with Unicode encoding, first create an .ini file by using the FileOpen() ; function with the mode parameter set to a Unicode parameter. ; Related .......: ; Dependencies ..: _LFN_FileExists, _LFN_FileReadToArray, _LFN_FileOpen, _LFN_FileWriteLine, _LFN_FileClose, _LFN_FileGetEncoding ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _LFN_IniWriteSection($sFile, $sSection, $xData, $iFirstEntry = 1) Local $sData If IsArray($xData) Then For $i = $iFirstEntry To UBound($xData) - 1 $sData = $sData & $xData[$i][0] & '=' & $xData[$i][1] & @CRLF Next Else $sData = StringReplace($xData, @LF, @CRLF) EndIf If _LFN_FileExists($sFile) Then Local $aFileLines = _LFN_FileReadToArray($sFile) If @error Then Return SetError(1, 0, 0) Local $iFirstLineToDelete = -1 Local $iLastLineToDelete = -1 Local $bSectionFound = False For $i = 0 To UBound($aFileLines) - 1 If StringLeft($aFileLines[$i], 1) = '[' Then If StringLeft($aFileLines[$i], StringLen($sSection) + 2) = '[' & $sSection & ']' Then $bSectionFound = True $iFirstLineToDelete = $i $iLastLineToDelete = UBound($aFileLines) - 1 Else If $bSectionFound Then ; entering next section $iLastLineToDelete = $i - 1 ExitLoop EndIf EndIf EndIf Next Local $hFile Local $bError If $iFirstLineToDelete > -1 And $iLastLineToDelete >= $iFirstLineToDelete Then $hFile = _LFN_FileOpen($sFile, 2 + _LFN_FileGetEncoding($sFile)) For $i = 0 To UBound($aFileLines) - 1 If $i >= $iFirstLineToDelete And $i <= $iLastLineToDelete Then ContinueLoop _LFN_FileWriteLine($hFile, $aFileLines[$i]) If @error Then $bError = True ExitLoop EndIf Next _LFN_FileClose($hFile) If $bError Then Return SetError(1, 0, 0) EndIf EndIf _LFN_FileWriteLine($sFile, '[' & $sSection & ']') If @error Then Return SetError(1, 0, 0) _LFN_FileWriteLine($sFile, $sData) If @error Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_LFN_IniWriteSection ; #INTERNAL_USE_ONLY# =========================================================================================================== ;__LFN_DllOpen ;__LFN_FileReadable ;__LFN_FilesExist ;__LFN_FilesListToArray ;__LFN_FilesSimilar ;__LFN_FileWritable ;__LFN_ReDim ;__LFN_ReDim2D ;__LFN_Target_IsExistingFile ;__LFN_Target_IsExistingFolder ;__LFN_Target_IsMask ;__LFN_Target_LastElement_Get ;__LFN_Target_LastElement_Trim ;__LFN_Target_RemoveTrailingBackslash ;__LFN_Target_SetUnicodePrefix ;__LFN_Target_UnSetUnicodePrefix ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_DllOpen ; Description ...: Opens "kernel32.dll" unless already opened. ; Syntax.........: __LFN_DllOpen() ; Parameters ....: none ; Return values .: Success - Returns a handle to "kernel32.dll" ; Failure - Returns -1 and sets @error to 1 ; Author ........: orbs ; Modified.......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_DllOpen() Local Static $hDLL If $hDLL < 1 Then $hDLL = DllOpen('kernel32.dll') If $hDLL < 1 Then Return SetError(1, 0, -1) Return $hDLL EndFunc ;==>__LFN_DllOpen ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FileReadable ; Description ...: Checks if a file can be read. ; Syntax.........: __LFN_FileReadable($sFile) ; Parameters ....: $sFile - Full path of a single file to check. ; Return values .: Success - Returns True if the file can be read. ; Failure - Returns False if the file cannot be read. ; Author ........: orbs ; Modified ......: ; Remarks .......: The check is done by opening the file for reading in binary mode and reading the first byte. ; Example: this funtion will return False when checking a PST file currently in use by Microsoft Outlook. ; @error is not used. ; Related .......: ; Dependencies ..: _LFN_FileGetSize, _LFN_FileOpen, _LFN_FileRead, _LFN_FileClose ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FileReadable($sFile) If _LFN_FileGetSize($sFile) = 0 Then Return True Local $hFile = _LFN_FileOpen($sFile, 16) _LFN_FileRead($hFile, 1) Local $nError = @error _LFN_FileClose($hFile) Return ($nError = 0) EndFunc ;==>__LFN_FileReadable ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesExist ; Description ...: Checks if the target exists, and if so, also checks its type (single file, multiple files, or folder). ; Syntax.........: __LFN_FilesExist($sTarget) ; Parameters ....: $sTarget - Full path to check (wildcards supported). ; Return values .: Success - Returns 1 if the target exists, and sets @extended: ; 0 - Target does not exist (therefore can not determine if it is a file or a folder) ; 1 - Target is a single file ; 2 - Target is multiple files ; 3 - Target is a folder ; Failure - Returns 0 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the target is a mask (i.e. contains wildcards): ; - For a success return, it is sufficient that at least one of the files matching the mask exists. ; - It is always considered as "multiple files" (@extended=2), even if only a single match exists. ; @error is not used. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesExist($sTarget) Local $nResult = 0 Local $nExtended = 0 If __LFN_Target_IsMask($sTarget) Then $nExtended = 2 ; multiple files $sTarget = __LFN_Target_SetUnicodePrefix($sTarget) Local $hSearch = FileFindFirstFile($sTarget) If $hSearch = -1 And Not FileExists($sTarget) Then ; not exist $nResult = 0 Else ; exists $nResult = 1 If $nExtended = 0 Then ; not yet determined if file or folder, but definitely not multiple files If StringInStr(FileGetAttrib($sTarget), 'D') Then ; folder $nExtended = 3 Else ; single file $nExtended = 1 EndIf EndIf EndIf FileClose($hSearch) Return SetExtended($nExtended, $nResult) EndFunc ;==>__LFN_FilesExist ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesListToArray ; Description ...: Creates a list of files. ; Syntax.........: __LFN_FilesListToArray($sMask[, $bRecurse = False]) ; Parameters ....: $sMask - Full path and mask of files to list (wildcards supported). ; $bRecurse - [optional] Set to True if to recurse subdirectories ; Return values .: Success - Returns a 1-D 1-based array of filesystem entries (files & subfolders) with unicode prefix: ; [0] = number of entries ; [1] = 1st entry ; [2] = 2nd entry ; [N] = Nth entry ; The count of files only is returned in @extended. ; Failure - Returns a 1-D array of one element [0] = 0, and sets @error to 1 ; Author ........: orbs ; Modified ......: ; Remarks .......: If the parameter is a folder, the files therein will be listed just as if you had used the * mask. ; Directories are listed with suffix backslash ("\"). ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesListToArray($sMask, $bRecurse = False) Local $aResult[1] = [0] Local $aTemp[1] = [0] Local $nExtended = 0 $sMask = __LFN_Target_SetUnicodePrefix($sMask) Local $sPath = '' Local $sMaskOnly = __LFN_Target_LastElement_Get($sMask) If Not StringInStr($sMaskOnly, '*') And Not StringInStr($sMaskOnly, '?') And StringInStr(FileGetAttrib($sMask), 'D') Then $sPath = $sMask $sMaskOnly = '*' $sMask = $sMask & '\' & $sMaskOnly Else $sPath = __LFN_Target_LastElement_Trim($sMask) EndIf If Not __LFN_FilesExist($sPath) Then Return SetExtended($nExtended, $aResult) Local $hSearch, $sFile, $i ; files $hSearch = FileFindFirstFile($sMask) While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sPath & '\' & $sFile), 'D') Then __LFN_ReDim($aResult, $sPath & '\' & $sFile & '\') Else __LFN_ReDim($aResult, $sPath & '\' & $sFile) $nExtended += 1 EndIf WEnd FileClose($hSearch) ; folders If $bRecurse Then $hSearch = FileFindFirstFile($sPath & '\*') While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sPath & '\' & $sFile), 'D') Then $aTemp = __LFN_FilesListToArray($sPath & '\' & $sFile & '\' & $sMaskOnly, $bRecurse) $nExtended += @extended If $aTemp[0] > 0 Then ReDim $aResult[$aResult[0] + 1 + $aTemp[0]] For $i = 1 To $aTemp[0] $aResult[$aResult[0] + $i] = $aTemp[$i] Next $aResult[0] += $aTemp[0] EndIf EndIf WEnd FileClose($hSearch) EndIf Return SetExtended($nExtended, $aResult) EndFunc ;==>__LFN_FilesListToArray ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FilesSimilar ; Description ...: Checks if two files have the same size and small-enough "Modified" timestamp difference. ; Syntax.........: __LFN_FilesSimilar($sFile1, $sFile2) ; Parameters ....: $sFile1 - first file to check similarity of. ; $sFile2 - second file to check similarity of. ; Return values .: Success - Returns 1 if the files are similar, or 0 otherwise and sets @extended: ; 1 - Difference of the "Modify" timestamp. ; 2 - Difference of size. ; Failure - Returns 0 and sets @error: ; 1 - At least one of the files was not found, or could not get timestamp of At least one of the files. ; 2 - At least one of the files was not found, or could not get size of At least one of the files. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: _LFN_FileGetTime, _LFN_FileGetSize ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_FilesSimilar($sFile1, $sFile2) Local $sTime1 = _LFN_FileGetTime($sFile1, 0, 1) If @error Then Return SetError(1, 0, 0) Local $sTime2 = _LFN_FileGetTime($sFile2, 0, 1) If @error Then Return SetError(1, 0, 0) If Abs(Number($sTime1) - Number($sTime2)) > 2 Then Return SetExtended(1, 0) Local $nSize1 = _LFN_FileGetSize($sFile1) If @error Then Return SetError(2, 0, 0) Local $nSize2 = _LFN_FileGetSize($sFile2) If @error Then Return SetError(2, 0, 0) If $nSize1 <> $nSize2 Then Return SetExtended(2, 0) Return 1 EndFunc ;==>__LFN_FilesSimilar ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_FileWritable ; Description ...: Checks if a file can be written to. ; Syntax.........: __LFN_FileWritable($sFile) ; Parameters ....: $sFile - Full path of a single file to check. ; Return values .: Success - Returns True if the file can be written to. ; Failure - Returns False if the file cannot be written to. ; Author ........: KaFu ; Modified ......: orbs ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: http://www.autoitscript.com/forum/topic/133076-looking-for-a-non-invasive-way-to-check-if-a-file-or-directory-is-writable-deletable-solved/ ; Example .......: No ; =============================================================================================================================== Func __LFN_FileWritable($sFile) Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', _ 'wstr', __LFN_Target_SetUnicodePrefix($sFile), _ 'dword', 2, _ 'dword', 7, _ 'struct*', 0, _ 'dword', 3, _ 'dword', 0x02000000, _ 'handle', 0) If @error Or $aRet[0] = Ptr(-1) Or $aRet[0] = 0 Then Return False DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $aRet[0]) Return True EndFunc ;==>__LFN_FileWritable ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_ReDim ; Description ...: Applies ReDim on a 1-D array in an efficient way. ; Syntax.........: __LFN_ReDim(ByRef $aArray[, $xData='']) ; Parameters ....: $aArray - The array to ReDim ; $xData - [optional] Data to add to the array ; Return values .: Returns the array after ReDim ; Author ........: guinness ; Modified.......: orbs ; Remarks .......: The returned array probably has empty cells at the end. the value at element [0] is the count of used cells, ; not the count of total cells. To work with the returned array, use element [0] to determine the last used cell ; instead of UBound. ; To truncate the array to used size: ReDim $aArray[$aArray[0]+1] ; Related .......: ; Dependencies ..: ; Link ..........: http://www.autoitscript.com/forum/topic/129689-redim-the-most-efficient-way-so-far-when-you-have-to-resize-an-existing-array/?hl=array+2d ; Example .......: No ; =============================================================================================================================== Func __LFN_ReDim(ByRef $aArray, $xData = '') Local $iNewRealSize = UBound($aArray) If $aArray[0] >= UBound($aArray) - 1 Then ; if used size = real size then must redim, otherwise do nothing $iNewRealSize = Ceiling((UBound($aArray) + 1) * 1.5) ReDim $aArray[$iNewRealSize] EndIf $aArray[0] += 1 ; anyway used size increased If $xData <> '' Then $aArray[$aArray[0]] = $xData EndFunc ;==>__LFN_ReDim ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_ReDim2D ; Description ...: Applies ReDim on a 2-D array in an efficient way. ; Syntax.........: __LFN_ReDim2D(ByRef $aArray[, $xData=''[, $sDelimiter='|']]) ; Parameters ....: $aArray - The array to ReDim ; $xData - [optional] Data to add to the array ; $sDelimiter - [optional] Delimiter to be used to separate data elements to columns ; Return values .: Returns the array after ReDim ; Author ........: orbs ; Modified.......: ; Remarks .......: The returned array probably has empty rows at the end. the value at element [0][0] is the count of used rows, ; not the count of total rows. To work with the returned array, use element [0][0] to determine the last used ; cell instead of UBound. ; To truncate the array to used size: ReDim $aArray[$aArray[0][0]+1][UBound($aArray,2)] ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_ReDim2D(ByRef $aArray, $xData = '', $sDelimiter = '|') Local $iNewRealSize = UBound($aArray) If $aArray[0][0] >= UBound($aArray) - 1 Then ; if used size = real size then must redim, otherwise do nothing $iNewRealSize = Ceiling((UBound($aArray) + 1) * 1.5) ReDim $aArray[$iNewRealSize][UBound($aArray, 2)] EndIf $aArray[0][0] += 1 ; anyway used size increased Local $aElements If $xData <> '' Then $aElements = StringSplit($xData, $sDelimiter) If $aElements[0] > UBound($aArray, 2) Then ReDim $aArray[$iNewRealSize][$aElements[0]] ; need to add columns For $i = 1 To $aElements[0] $aArray[$aArray[0][0]][$i - 1] = $aElements[$i] Next EndIf EndFunc ;==>__LFN_ReDim2D ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsExistingFile ; Description ...: Checks if the target is a single file that exists and is not a folder. ; Syntax.........: __LFN_Target_IsExistingFile($sTarget) ; Parameters ....: $sTarget - Full path to check. ; Return values .: True if the target is an existing file. ; False if the target is a mask, a folder, or does not exist. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsExistingFile($sTarget) If __LFN_FilesExist($sTarget) And @extended = 1 Then Return True Return False EndFunc ;==>__LFN_Target_IsExistingFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsExistingFolder ; Description ...: Checks if the target is a folder that exists. ; Syntax.........: __LFN_Target_IsExistingFolder($sTarget) ; Parameters ....: $sTarget - Full path to check. ; Return values .: True if the target is an existing folder. ; False if the target is a mask, a file, or does not exist. ; Author ........: orbs ; Modified ......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsExistingFolder($sTarget) If __LFN_FilesExist($sTarget) And @extended = 3 Then Return True Return False EndFunc ;==>__LFN_Target_IsExistingFolder ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_IsMask ; Description ...: Checks if the target is multiple files (includes wildcards). ; Syntax.........: __LFN_Target_IsMask($sTarget) ; Parameters ....: $sTarget - Full path to check (wildcards supported). ; Return values .: True if the target is multiple files. ; False if the target is a single file. ; Author ........: orbs ; Modified ......: ; Remarks .......: If the target is a folder then it is not multiple files, therefore False is returned. ; The target does not have to exist. ; Related .......: ; Dependencies ..: __LFN_Target_LastElement_Get ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_IsMask($sTarget) Local $sLastElement = __LFN_Target_LastElement_Get($sTarget) If (StringInStr($sLastElement, '*') Or StringInStr($sLastElement, '?')) Then Return True Return False EndFunc ;==>__LFN_Target_IsMask ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_LastElement_Get ; Description ...: Isolates the last filesystem element of a target - what's after the last backslash ("\") character. ; Syntax.........: __LFN_Target_LastElement_Get($sTarget[, $sDelimiter = '\']) ; Parameters ....: $sTarget - Filesystem element to check (wildcards supported). ; $sDelimiter - Delimiter to determine the last element ; Return values .: A string of the last filesystem element. ; Author ........: orbs ; Modified ......: ; Remarks .......: $sDelimiter MUST be a single character! ; The target does not have to exist. ; The return string does not begin with the leading delimiter. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_LastElement_Get($sTarget, $sDelimiter = '\') Local $sTargetUnset = __LFN_Target_UnSetUnicodePrefix($sTarget) Local $iPos = StringInStr($sTargetUnset, $sDelimiter, 0, -1) Return StringTrimLeft($sTargetUnset, $iPos) EndFunc ;==>__LFN_Target_LastElement_Get ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_LastElement_Trim ; Description ...: Trims the last filesystem element of a target and returns what's before the last backslash ("\") character. ; Syntax.........: __LFN_Target_LastElement_Trim($sTarget[, $sDelimiter = '\']) ; Parameters ....: $sTarget - Filesystem element to check (wildcards supported). ; $sDelimiter - Delimiter to determine the last element ; Return values .: A string of the target with the last filesystem element stripped from it. ; Author ........: orbs ; Modified ......: ; Remarks .......: $sDelimiter MUST be a single character! ; The target does not have to exist. ; The return string does not end with the trailing delimiter. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_LastElement_Trim($sTarget, $sDelimiter = '\') Local $sTargetUnset = __LFN_Target_UnSetUnicodePrefix($sTarget) Local $iPos = StringInStr($sTargetUnset, $sDelimiter, 0, -1) Return __LFN_Target_SetUnicodePrefix(StringLeft($sTargetUnset, $iPos - 1)) EndFunc ;==>__LFN_Target_LastElement_Trim ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_RemoveTrailingBackslash ; Description ...: Strips all trailing backslash characters ("\") from the end of the given target path. ; Syntax.........: __LFN_Target_RemoveTrailingBackslash($sTarget) ; Parameters ....: $sTarget - Target path to remove trailing backslash characters from (wildcards supported). ; Return values .: A string of the target path without trailing backslash. ; @extended holds the number of backslash characters removed. ; Author ........: orbs ; Modified ......: ; Remarks .......: The target does not have to exist. ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_RemoveTrailingBackslash($sTarget) Local $nBackslashedRemoved = 0 While StringRight($sTarget, 1) = '\' $sTarget = StringTrimRight($sTarget, 1) $nBackslashedRemoved += 1 WEnd Return SetExtended($nBackslashedRemoved, $sTarget) EndFunc ;==>__LFN_Target_RemoveTrailingBackslash ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_SetUnicodePrefix ; Description ...: Adds the unicode prefix to a given target, unless already present or some conditios are mey - see Remarks. ; Syntax.........: __LFN_Target_SetUnicodePrefix($sTarget) ; Parameters ....: $sTarget - Path to prefix with the unicode prefix ("\\?\" or "\\?\UNC\"). ; Return values .: Returns the parameter with the unicode prefix and sets @extended: ; 1 - $sTarget is on a locally mounted volume (local drive, mapped network drive, etc.) ; 2 - $sTarget is on a network share (UNC path) ; Author ........: orbs ; Modified.......: ; Remarks .......: The unicode prefix is added only if needed. it is not added under these conditions: ; $sTarget already has the unicode prefix ; $sTarget is a drive root ; $sTarget is a relative path ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_SetUnicodePrefix($sTarget) If (StringLeft($sTarget, 4) = '\\?\') Then $sTarget = __LFN_Target_UnSetUnicodePrefix($sTarget) ; remove unicode prefix in case it's a drive root If (StringLen($sTarget) = 2 And StringRight($sTarget, 1) = ':') Or (StringLen($sTarget) = 3 And StringRight($sTarget, 2) = ':\') Then Return $sTarget ; $sTarget is a drive root If StringLeft($sTarget, 2) <> '\\' And StringMid($sTarget, 2, 1) <> ':' Then Return $sTarget ; $sTarget is a relative path ; before adding prefix, embody relative elements "\.." Local $iPos, $iPosPrevBackslash, $sSubstringToReplace While True $iPos = StringInStr($sTarget, '\..') If $iPos = 0 Then ExitLoop $iPosPrevBackslash = $iPos Do $iPosPrevBackslash -= 1 Until StringMid($sTarget, $iPosPrevBackslash, 1) = '\' Or $iPos = 0 $sSubstringToReplace = StringMid($sTarget, $iPosPrevBackslash, $iPos - $iPosPrevBackslash + 3) $sTarget = StringReplace($sTarget, $sSubstringToReplace, '', 1) WEnd ; now add the unicode prefix and return If StringLeft($sTarget, 2) = '\\' Then Return SetExtended(2, '\\?\UNC\' & StringTrimLeft($sTarget, 2)) Else Return SetExtended(1, '\\?\' & $sTarget) EndIf EndFunc ;==>__LFN_Target_SetUnicodePrefix ; #FUNCTION# ==================================================================================================================== ; Name ..........: __LFN_Target_UnSetUnicodePrefix ; Description ...: Removes the unicode prefix from a given target. ; Syntax.........: __LFN_Target_UnSetUnicodePrefix($sTarget) ; Parameters ....: $sTarget - Filesystem element to remove the unicode prefix ("\\?\" or "\\?\UNC\") from. ; Return values .: Returns the parameter without the unicode prefix and sets @extended: ; 0 - The unicode prefix was not found. ; 1 - $sTarget is on a locally mounted volume (local drive, mapped network drive, etc.) ; 2 - $sTarget is on a network share (UNC path) ; Author ........: orbs ; Modified.......: ; Remarks .......: ; Related .......: ; Dependencies ..: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __LFN_Target_UnSetUnicodePrefix($sTarget) If (StringLeft($sTarget, 8) = '\\?\UNC\') Then Return SetExtended(2, '\\' & StringTrimLeft($sTarget, 8)) If (StringLeft($sTarget, 4) = '\\?\') Then Return SetExtended(1, StringTrimLeft($sTarget, 4)) Return $sTarget EndFunc ;==>__LFN_Target_UnSetUnicodePrefix demo script: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 AutoItSetOption('TrayIconDebug',1) #include <Array.au3> ; included only for a call to _ArrayDisplay #include 'LFN.au3' ; INIT ; - declare root of test folder Global $sLFN_Root='C:\TEMP\LFN' ; - declare element of path - create an element (subfolder) of 200 characters in length. two of those, and you're off limit. Global $sLFN_Element='' For $i=1 To 20 $sLFN_Element=$sLFN_Element&'_-_-_-_'&StringFormat('%03d',$i*10) Next ; - declare 3 levels of path lengths: Global $sLFN_L0=$sLFN_Root ; level 0 is the root of the test folder Global $sLFN_L1=$sLFN_L0&'\'&$sLFN_Element ; level 1 is one element deep (total 212 characters) - still OK Global $sLFN_L2=$sLFN_L1&'\'&$sLFN_Element ; level 2 is two elements deep (total 413 characters) - off limit! Global $sLFN_L3=$sLFN_L2&'\'&$sLFN_Element ; level 3 is three elements deep (total 614 characters) - way off limit! ; MAIN ; - prepare folder structure _LFN_DirRemove($sLFN_L0,1) ; delete the 1st test folder to begin blank _LFN_DirRemove($sLFN_L0&'2',1) ; delete the 2nd test folder to begin blank _LFN_DirRemove($sLFN_L0&'3',1) ; delete the 3rd test folder to begin blank MsgBox(0,'Checkpoint','check clear folder now.') _LFN_DirCreate($sLFN_L3) ; create the deepest level L3 ; - file manipulation _LFN_FileWriteLine($sLFN_L3&'\file1.txt','this is a line of text') ; create a file by writing a line to a new file Global $hFile=_LFN_FileOpen($sLFN_L3&'\file1.txt',1) ; do some file manipulation _LFN_FileWriteLine($hFile,'this is a line of text') ; add a line to the file _LFN_FileSetPos($hFile,-14,2) ; beginning of the word "line" _LFN_FileWrite($hFile,'LINE') ; capitalize the word "line" _LFN_FileFlush($hFile) ; apply the change _LFN_FileSetPos($hFile,-4,1) ; back MsgBox(0,'_LFN_FileGetPos',_LFN_FileGetPos($hFile)) MsgBox(0,'_LFN_FileRead (4 chars)',_LFN_FileRead($hFile,4)) ; read the change _LFN_FileSetEnd($hFile) ; truncate the rest of the line _LFN_FileClose($hFile) ; done for now _LFN_FileSetTime($sLFN_L3&'\file1.txt','20011231010203') ; - test file info Global $aFileLines=_LFN_FileReadToArray($sLFN_L3&'\file1.txt') _ArrayDisplay($aFileLines,'_LFN_FileReadToArray') Global $hSearch=_LFN_FileFindFirstFile($sLFN_L3&'\file1.txt') Global $sShortName=_LFN_FileGetShortName($sLFN_L3&'\file1.txt') Global $sLongName=_LFN_FileGetLongName($sShortName) MsgBox(0,'test file information', _ '_LFN_FileExists = '&_LFN_FileExists($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileFindNextFile = '&_LFN_FileFindNextFile($hSearch)&@CR&@CR& _ '_LFN_FileRead (entire file) = '&@CR&_LFN_FileRead($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileReadLine (last line) = '&_LFN_FileReadLine($sLFN_L3&'\file1.txt',-1)&@CR&@CR& _ '_LFN_FileGetSize = '&_LFN_FileGetSize($sLFN_L3&'\file1.txt')&@CR&@CR& _ '_LFN_FileGetTime = '&_LFN_FileGetTime($sLFN_L3&'\file1.txt',0,1)&@CR&@CR& _ '_LFN_FileGetShortName = '&$sShortName&@CR&@CR& _ '_LFN_FileGetLongName (from short name) = '&$sLongName) _LFN_FileClose($hSearch) ; - exe file info _LFN_FileCopy(@AutoItExe,$sLFN_L3) MsgBox(0,'EXE file information', _ '_LFN_FileGetVersion (not specified) = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe')&@CR& _ '_LFN_FileGetVersion (empty string) = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe','')&@CR& _ '_LFN_FileGetVersion ("FileVersion") = '&_LFN_FileGetVersion($sLFN_L3&'\AutoIt3.exe','FileVersion')&@CR&@CR& _ '_LFN_FileGetEncoding = '&_LFN_FileGetEncoding($sLFN_L3&'\AutoIt3.exe')) ; - file copy, rename, move _LFN_FileCopy($sLFN_L3&'\file1.txt',$sLFN_L2) MsgBox(0,'Checkpoint','file copy L3 -> L2') _LFN_FileMove($sLFN_L2&'\file1.txt',$sLFN_L2&'\renamed1.txt') MsgBox(0,'Checkpoint','file rename L2\file1.txt -> L2\renamed1.txt') _LFN_FileMove($sLFN_L2&'\renamed1.txt',$sLFN_L3) MsgBox(0,'Checkpoint','file move L2\renamed1.txt -> L3') _LFN_FileCopy($sLFN_L3,$sLFN_L2) MsgBox(0,'Checkpoint','file copy L3 -> L2') _LFN_FileDelete($sLFN_L2) MsgBox(0,'Checkpoint','file delete L2') ; - folder copy, rename, move, hide/unhide _LFN_DirCopy($sLFN_L0,$sLFN_L0&'2') MsgBox(0,'Checkpoint','dir copy <L0> -> <L02>') _LFN_DirMove($sLFN_L0,$sLFN_L0&'2',1) MsgBox(0,'Checkpoint','dir move <L0> -> <L02> (inside)') _LFN_DirCopy($sLFN_L0&'2\LFN',$sLFN_L0) MsgBox(0,'Checkpoint','dir copy <L02>\LFN -> <L0>') _LFN_FileSetAttrib($sLFN_L0,'+H') MsgBox(0,'Checkpoint','dir hidden <L0>'&@CR&@CR&'dir attrib: '&_LFN_FileGetAttrib($sLFN_L0)) _LFN_FileSetAttrib($sLFN_L0,'-H') MsgBox(0,'Checkpoint','dir unhidden <L0>'&@CR&@CR&'dir attrib: '&_LFN_FileGetAttrib($sLFN_L0)) ; - folder size Global $aDirSize=_LFN_DirGetSize($sLFN_L0,1) MsgBox(0,'Checkpoint','dir size <L0>: '&@CR&@CR& _ 'Size [bytes] = '&$aDirSize[0]&@CR& _ 'Files count = '&$aDirSize[1]&@CR& _ 'Folders count = '&$aDirSize[2]) ; - ini functions Global $sIniFile1=$sLFN_L3&'\test1.ini' Global $sIniFile2=$sLFN_L3&'\test2.ini' MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K1) = '&_LFN_IniWrite($sIniFile1,'S1','S1K1','""S1V1 inside double-souble-quotes to be stripped""')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection (S2) = '&_LFN_IniWriteSection($sIniFile1,'S2','S2K1= S2V1 with whitespaces NOT to be stripped '&@LF&'S2K2="S2V2 inside double-quotes NOT to be stripped"'&@LF&'S2K3=V3')) MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K2) = '&_LFN_IniWrite($sIniFile1,'S1','S1K2','" S1V2 with quoted whitespaces "')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection (S3) = '&_LFN_IniWriteSection($sIniFile1,'S3','S3K1=V1'&@LF&'S3K2=V2'&@LF&'S3K3=V3')) MsgBox(0,'Checkpoint','_LFN_IniWrite (S1K3) = '&_LFN_IniWrite($sIniFile1,'S1','S1K3','V3')) MsgBox(0,'Checkpoint','_LFN_IniRead (S1K2) = '&_LFN_IniRead($sIniFile1,'S1','S1K2','S1K2: could not read value')) Global $a $a=_LFN_IniReadSection($sIniFile1,'S3') $a[1][1]='"V1 with quotes"' $a[2][1]=' V2 with whitespace ' MsgBox(0,'Checkpoint','_LFN_IniDelete 1:(S3) = '&_LFN_IniDelete($sIniFile1,'S3')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection 2:(S3) = '&_LFN_IniWriteSection($sIniFile2,'S3',$a)) $a=_LFN_IniReadSection($sIniFile1,'S2') MsgBox(0,'Checkpoint','_LFN_IniDelete 1:(S2K2) = '&_LFN_IniDelete($sIniFile1,'S2','S2K2')) MsgBox(0,'Checkpoint','_LFN_IniWriteSection 2:(S2) = '&_LFN_IniWriteSection($sIniFile2,'S2',$a)) MsgBox(0,'Checkpoint','_LFN_IniRenameSection 2:(S2) = '&_LFN_IniRenameSection($sIniFile2,'S2','S2renamed')) Global $aSectionNames=_LFN_IniReadSectionNames($sIniFile2) _ArrayDisplay($aSectionNames,'section names') For $i=1 To $aSectionNames[0] $a=_LFN_IniReadSection($sIniFile2,$aSectionNames[$i]) _ArrayDisplay($a,$aSectionNames[$i]) Next script converter: #NoTrayIcon #Region refs ; http://www.autoitscript.com/forum/topic/135536-how-to-make-the-gui-resizable/ ; https://www.autoitscript.com/wiki/Adding_UDFs_to_AutoIt_and_SciTE ; https://www.autoitscript.com/autoit3/docs/appendix/WinMsgCodes.htm #EndRegion refs #Region AutoIt3Wrapper directives section #AutoIt3Wrapper_Icon=LFN_Script_Converter_NG.ico #AutoIt3Wrapper_UseUpx=N #AutoIt3Wrapper_Res_Fileversion=1.4.0.3 #EndRegion AutoIt3Wrapper directives section #Region include #include <StaticConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <ComboConstants.au3> #include <GuiButton.au3> #EndRegion include #Region declare ; declare Global $aFuncs[1] = [0] Global $sScript_File = '' Global $aScriptOrg[1] = [0] Global $aScriptNew[1] = [0] Global $aLineChanged[1][3] Global $iLineChanged = 0 Global $bNeedToInclude = True ; assume the LFN UDF is not alredy included Global $iLineOfLastInclude = 0 ; after this line number, the line to include the LFN UDF will be added Global $tPoint_MainGlobal = DllStructCreate($tagPoint) ; ListView tooltips ; declare and populate possible UDF paths Global $sUDF_Path_MainInclude = RegRead('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude = '' Then $sUDF_Path_MainInclude = RegRead('HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude = '' Then $sUDF_Path_MainInclude = RegRead('HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3', 'UninstallString') If $sUDF_Path_MainInclude <> '' Then $sUDF_Path_MainInclude = StringLeft($sUDF_Path_MainInclude, StringInStr($sUDF_Path_MainInclude, '\', 0, -1) - 1) If $sUDF_Path_MainInclude <> '' Then $sUDF_Path_MainInclude &= '\Include' Global $sUDF_Path_UserInclude = RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include') ; declare UDF properties Global $sUDF_Name = 'LFN.au3' Global $sUDF = '' Global $sUDF_Version = '' Global $sUDF_AutoItVersion = '' Global $sUDF_FunctionsList = '' ; declare and init preferences Global $bMonospace = False Global $bCreateBackup = True Global $bIncludeUDF = True Global $bConvertFileFindNextFile = False #EndRegion declare #Region build GUI $hGUI = GUICreate('LFN Script Converter', 500, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_SYSMENU)) GUISetBkColor(0xFEDCBA) $iLine_Y = 25 GUICtrlCreateGroup('UDF', 10, $iLine_Y - 18, 355, 40) RemoveTheme(GUICtrlGetHandle(-1)) GUICtrlSetColor(-1, 0x876543) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlCreateLabel('Location:', 20, $iLine_Y, 50, 16) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gUDF_Path = GUICtrlCreateCombo('Script folder', 75, $iLine_Y - 4, 160, 100, $CBS_DROPDOWNLIST) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) If $sUDF_Path_MainInclude <> '' Then GUICtrlSetData(-1, 'AutoIt main include folder') If $sUDF_Path_UserInclude <> '' Then GUICtrlSetData(-1, 'AutoIt user include folder') GUICtrlCreateLabel('Name:', 250, $iLine_Y, 35, 16) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gUDF_Name = GUICtrlCreateInput($sUDF_Name, 285, $iLine_Y - 2, 70, 18) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $gPref = GUICtrlCreateLabel(Chr(64), 459, $iLine_Y - 4, 20, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetFont(-1, 18, Default, 0, 'Webdings') GUICtrlSetCursor(-1, 0) GUICtrlSetColor(-1, 0x876543) GUICtrlSetTip(-1, 'Preferences') $gPref_Menu_Dummy = GUICtrlCreateDummy() $gPref_Menu = GUICtrlCreateContextMenu($gPref_Menu_Dummy) $gPref_Menu_Monospace = GUICtrlCreateMenuItem('Monospace Font', $gPref_Menu) $gPref_Menu_CreateBackup = GUICtrlCreateMenuItem('Create Backup', $gPref_Menu) If $bCreateBackup Then GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_CHECKED) $gPref_Menu_IncludeUDF = GUICtrlCreateMenuItem('Include UDF', $gPref_Menu) If $bIncludeUDF Then GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_CHECKED) $gPref_Menu_ConvertFileFindNextFile = GUICtrlCreateMenuItem('Convert FileFindNextFile', $gPref_Menu) If $bConvertFileFindNextFile Then GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_CHECKED) $iLine_Y = 73 GUICtrlCreateGroup('Script', 10, $iLine_Y - 18, 480, 40) RemoveTheme(GUICtrlGetHandle(-1)) GUICtrlSetColor(-1, 0x876543) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT)) $gScript_File = GUICtrlCreateInput('', 20, $iLine_Y - 2, 265, 18) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT)) $gScript_Select = GUICtrlCreateButton('Browse', 290, $iLine_Y - 3, 60, 20) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) $gScript_Convert = GUICtrlCreateButton('Convert', 355, $iLine_Y - 3, 125, 20, $BS_SPLITBUTTON) GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) $gScript_Convert_Menu_Dummy = GUICtrlCreateDummy() $gScript_Convert_Menu = GUICtrlCreateContextMenu($gScript_Convert_Menu_Dummy) $gScript_Convert_Menu_QueryUDF = GUICtrlCreateMenuItem('Query UDF', $gScript_Convert_Menu) $gScript_Convert_Menu_Analyze = GUICtrlCreateMenuItem('Analyze', $gScript_Convert_Menu) $gScript_Convert_Menu_Convert = GUICtrlCreateMenuItem('Convert', $gScript_Convert_Menu) $gLV = GUICtrlCreateListView('Line#|Original|Converted', 10, 100, 480, 370) GUICtrlSetFont(-1, Default, Default, Default, 'Tahoma') $hLV = GUICtrlGetHandle($gLV) _GUICtrlListView_SetColumnWidth($gLV, 0, 50) _GUICtrlListView_SetColumnWidth($gLV, 1, 200) _GUICtrlListView_SetColumnWidth($gLV, 2, 200) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUISetState() ControlFocus('', '', $gScript_File) GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") GUIRegisterMsg($WM_SIZE, "_WM_SIZE") GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; for context menu of split button #EndRegion build GUI ; work with GUI While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_RESTORE, $GUI_EVENT_MAXIMIZE _WM_SIZE($hGUI, -1, -1, -1) Case $GUI_EVENT_MOUSEMOVE SetMousePos() TimerFunc($hLV) Case $gScript_Convert_Menu_QueryUDF If UDF_Query() Then MsgBox(0, 'UDF Info:', _ 'UDF Full Path:' & @TAB & $sUDF & @CR & _ 'UDF Version:' & @TAB & $sUDF_Version & @CR & _ 'AutoIt Version:' & @TAB & $sUDF_AutoItVersion & @CR & _ 'Functions List:' & @TAB & '(' & $aFuncs[0] & ' functions)' & @CR & _ $sUDF_FunctionsList) Case $gScript_Select $sScript_File = FileOpenDialog('Select an AutoIt v3 Script to convert:', @ScriptDir, 'AutoIt v3 Scripts (*.au3)') If Not @error Then GUICtrlSetData($gScript_File, $sScript_File) Call_Analyze() EndIf Case $gScript_Convert_Menu_Analyze Call_Analyze() Case $gScript_Convert, $gScript_Convert_Menu_Convert If Call_Analyze() Then Convert() Case $gPref _ContextMenu_ShowMenu($hGUI, $gPref, $gPref_Menu, -180) Case $gPref_Menu_Monospace $bMonospace = Not $bMonospace If $bMonospace Then GUICtrlSetState($gPref_Menu_Monospace, $GUI_CHECKED) GUICtrlSetFont($gLV, Default, Default, Default, 'Courier New') Else GUICtrlSetState($gPref_Menu_Monospace, $GUI_UNCHECKED) GUICtrlSetFont($gLV, Default, Default, Default, 'Tahoma') EndIf Case $gPref_Menu_CreateBackup $bCreateBackup = Not $bCreateBackup If $bCreateBackup Then GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_CreateBackup, $GUI_UNCHECKED) EndIf Case $gPref_Menu_IncludeUDF $bIncludeUDF = Not $bIncludeUDF If $bIncludeUDF Then GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_IncludeUDF, $GUI_UNCHECKED) EndIf Case $gPref_Menu_ConvertFileFindNextFile $bConvertFileFindNextFile = Not $bConvertFileFindNextFile If $bConvertFileFindNextFile Then GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_CHECKED) Else GUICtrlSetState($gPref_Menu_ConvertFileFindNextFile, $GUI_UNCHECKED) EndIf EndSwitch WEnd Func Call_Analyze() If GUICtrlRead($gScript_File) = '' Then MsgBox(16, 'Error!', 'Please select a script file to convert. ', 0, $hGUI) Return False EndIf _GUICtrlListView_DeleteAllItems($gLV) If Not UDF_Query() Then Return False If Analyze() Then For $i = 1 To $iLineChanged GUICtrlCreateListViewItem($aLineChanged[$i][0] & '|' & StringStripWS($aLineChanged[$i][1], 3) & '|' & StringStripWS($aLineChanged[$i][2], 3), $gLV) Next Else MsgBox(64, 'Abort', 'Conversion aborted.' & @CR & @CR & 'No changes need to be made. Script is either already converted or does not use any functions to be converted. ', 0, $hGUI) GUICtrlSetData($gScript_File, '') Return False EndIf Return True EndFunc ;==>Call_Analyze Func UDF_Query() Local $sScript_Path = '' $sUDF_Name = GUICtrlRead($gUDF_Name) If $sUDF_Name = '' Then MsgBox(16, 'Error!', 'Please type the UDF file name. ', 0, $hGUI) Return False EndIf Switch GUICtrlRead($gUDF_Path) Case 'Script folder' $sScript_Path = GUICtrlRead($gScript_File) If $sScript_Path = '' Then $sScript_Path = @ScriptDir Else $sScript_Path = StringLeft($sScript_Path, StringInStr($sScript_Path, '\', 0, -1) - 1) EndIf $sUDF = $sScript_Path & '\' & $sUDF_Name Case 'AutoIt main include folder' $sUDF = $sUDF_Path_MainInclude & '\' & $sUDF_Name Case 'AutoIt user include folder' $sUDF = $sUDF_Path_UserInclude & '\' & $sUDF_Name Case Else MsgBox(16, 'Error!', 'Unknown item in locations list. ', 0, $hGUI) Return False EndSwitch If Not FileExists($sUDF) Then MsgBox(16, 'Error!', 'UDF file not found: ' & @CR & @CR & $sUDF, 0, $hGUI) Return False EndIf $sUDF_Version = 'n/a' $sUDF_AutoItVersion = 'n/a' $sUDF_FunctionsList = '' ReDim $aFuncs[1] $aFuncs[0] = 0 $aUDF = __FileReadToArray($sUDF) Local $bListFuncs = False For $i = 1 To UBound($aUDF) - 1 If StringLeft($aUDF[$i], 19) = '; UDF Version ...: ' Then $sUDF_Version = StringTrimLeft($aUDF[$i], 19) If StringLeft($aUDF[$i], 19) = '; AutoIt Version : ' Then $sUDF_AutoItVersion = StringTrimLeft($aUDF[$i], 19) If $bListFuncs Then If $aUDF[$i] = '; ===============================================================================================================================' Then ExitLoop $aFuncs[0] += 1 ReDim $aFuncs[$aFuncs[0] + 1] $aFuncs[$aFuncs[0]] = StringTrimLeft($aUDF[$i], 6) ; remove the string ";_LFN_" and leave only the native name of the function $sUDF_FunctionsList = $sUDF_FunctionsList & @TAB & $aFuncs[$aFuncs[0]] & @CR EndIf If $aUDF[$i] = '; #CURRENT# =====================================================================================================================' Then $bListFuncs = True Next If $aFuncs[0] = 0 Then MsgBox(16, 'Error!', 'No functions found in the LFN UDF file: ' & @CR & @CR & $sUDF, 0, $hGUI) Return False EndIf Return True EndFunc ;==>UDF_Query Func Analyze() ; init ReDim $aLineChanged[1][3] $aLineChanged[0][0] = 0 $aLineChanged[0][1] = 0 $aLineChanged[0][2] = 0 $iLineChanged = 0 $bNeedToInclude = True $iLineOfLastInclude = 0 ; read existing script to memory $aScriptOrg = __FileReadToArray($sScript_File) ; match size of new array ReDim $aScriptNew[UBound($aScriptOrg)] $aScriptNew[0] = UBound($aScriptNew) - 1 ; in memory, replace functions line-by-line, while searching for the last #include and checking if LFN UDF is not already included For $i = 1 To UBound($aScriptOrg) - 1 If StringInStr($aScriptOrg[$i], '#include ') Then $iLineOfLastInclude = $i If StringInStr($aScriptOrg[$i], $sUDF_Name) Then $bNeedToInclude = False EndIf $aScriptNew[$i] = ReplaceAllFuncs($aScriptOrg[$i]) If @extended Then $iLineChanged += 1 ReDim $aLineChanged[$iLineChanged + 1][3] $aLineChanged[$iLineChanged][0] = $i $aLineChanged[$iLineChanged][1] = $aScriptOrg[$i] $aLineChanged[$iLineChanged][2] = $aScriptNew[$i] EndIf Next ; control #1 - if no changes are required then exit If $iLineChanged = 0 Then Return False ; done analyze Return True EndFunc ;==>Analyze Func Convert() ToolTip('') ; summary report Local $sUDF_IncludeString = '' Local $sText = '' If $bCreateBackup Then $sText = $sText & '- Original file will be backed-up.' & @CR $sText = $sText & '- ' & $iLineChanged & ' lines will be modified.' & @CR If $bNeedToInclude And $bIncludeUDF Then $sText &= '- The statement #include ' If GUICtrlRead($gUDF_Path) = 'Script folder' Then $sUDF_IncludeString = '"' & $sUDF_Name & '"' Else $sUDF_IncludeString = '<' & $sUDF_Name & '>' EndIf $sText &= $sUDF_IncludeString $sText &= ' will be added ' If $iLineOfLastInclude = 0 Then $sText &= 'at the top of the script. ' Else $sText &= 'after line #' & $iLineOfLastInclude & ': ' & @CR & ' ' & $aScriptOrg[$iLineOfLastInclude] EndIf Else $sText &= '- #include statement will not be added.' EndIf If MsgBox(32 + 4, 'Conversion Summary:', $sText & @CR & @CR & 'Continue with the conversion?', 0, $hGUI) <> 6 Then MsgBox(64, 'Abort', 'Conversion aborted. No changes were made. ', 0, $hGUI) Return EndIf ; backup existing script If $bCreateBackup And Not FileCopy($sScript_File, $sScript_File & '.PreLFN_' & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & '.au3') Then MsgBox(16, 'Error!', 'Could not create a backup of the script before conversion. ', 0, $hGUI) Return EndIf ; rewrite the script Local $hScriptFile = FileOpen($sScript_File, 2) For $i = 1 To UBound($aScriptNew) - 1 If $bNeedToInclude And $bIncludeUDF And $i = $iLineOfLastInclude + 1 Then FileWriteLine($hScriptFile, '#include ' & $sUDF_IncludeString) If Not FileWriteLine($hScriptFile, $aScriptNew[$i]) Then MsgBox(16, 'Error!', 'Could not write line #' & $i & ' to the script file. ' & @CR & @CR & 'IMPORTANT: to avoid issues, you are advised to revert to the backup copy of your script. ', 0, $hGUI) FileClose($hScriptFile) Return EndIf Next FileClose($hScriptFile) MsgBox(64, 'Done', 'Conversion completed successfully. ', 0, $hGUI) EndFunc ;==>Convert Func ReplaceAllFuncs($sLine) ; isolate LFN UDF internal functions Local $sLineNew = StringReplace($sLine, '__LFN_', '__L!N_') ; revert any LFN UDF current functinos back to their native form $sLineNew = StringReplace($sLineNew, '_LFN_', '') ; convert functions to LFN For $i = 1 To $aFuncs[0] $sLineNew = StringRegExpReplace($sLineNew, "(?<!\w)(" & $aFuncs[$i] & '\(' & ")", '_LFN_' & $aFuncs[$i] & '(') Next ; revert isolation of LFN UDF internal functions $sLineNew = StringReplace($sLineNew, '__L!N_', '__LFN_') ; revert conversion of FileFindNextFile if needed If Not $bConvertFileFindNextFile Then $sLineNew = StringReplace($sLineNew, '_LFN_FileFindNextFile', 'FileFindNextFile') ; return the converted line with indication if it was changed or not If $sLineNew = $sLine Then Return SetExtended(0, $sLineNew) Else Return SetExtended(1, $sLineNew) EndIf EndFunc ;==>ReplaceAllFuncs Func __FileReadToArray($xFile) Return StringSplit(StringStripCR(FileRead($xFile, FileGetSize($xFile))), @LF) EndFunc ;==>__FileReadToArray Func RemoveTheme($hItem) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $hItem, "wstr", 0, "wstr", 0) EndFunc ;==>RemoveTheme #Region resizing funcs Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $hGUI Then $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($tagMaxinfo, 7, 500) ; min X DllStructSetData($tagMaxinfo, 8, 300) ; min Y Return 0 EndIf EndFunc ;==>_WM_GETMINMAXINFO Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam) If $hWnd = $hGUI Then $aLVPos = ControlGetPos($hGUI, "", $gLV) If @error Then Return Local $nLV_ColWidth = ($aLVPos[2] - 80) / 2 _GUICtrlListView_SetColumnWidth($gLV, 0, 50) _GUICtrlListView_SetColumnWidth($gLV, 1, $nLV_ColWidth) _GUICtrlListView_SetColumnWidth($gLV, 2, $nLV_ColWidth) EndIf EndFunc ;==>_WM_SIZE #EndRegion resizing funcs #Region ListView tooltip funcs Func TimerFunc($hLV) Local Const $nLinesAround = 10 Local Static $iIndex_old = -1 Local $iIndex = _GUICtrlListView_HitTest($hLV) If HoveringOnHeader($hLV) Or $iIndex[0] < 0 Then $iIndex_old = -1 Return ToolTip('') EndIf If $iIndex[0] = $iIndex_old Then Return Local $iLine = $aLineChanged[$iIndex[0] + 1][0] Local $iLineStart = 1 If $iLine - $nLinesAround > 1 Then $iLineStart = $iLine - $nLinesAround Local $iLineEnd = $iLine + $nLinesAround If UBound($aScriptNew) - 1 < $iLine + $nLinesAround Then $iLineEnd = UBound($aScriptNew) - 1 Local $sTooltip = '' For $i = $iLineStart To $iLineEnd $sTooltip = $sTooltip & $i & '.' & @TAB & $aScriptNew[$i] & @CR Next ; create tooltip ToolTip($sTooltip, Default, Default, 'Line #' & $iLine & ':', Default, 4) $iIndex_old = $iIndex[0] EndFunc ;==>TimerFunc Func SetMousePos() DllStructSetData($tPoint_MainGlobal, 1, MouseGetPos(0)) DllStructSetData($tPoint_MainGlobal, 2, MouseGetPos(1)) EndFunc ;==>SetMousePos Func HoveringOnHeader($hLV) Local $tRect = DllStructCreate($tagRect) Local $aPos = WinGetPos(_GUICtrlListView_GetHeader($hLV)) $aPos[2] = $aPos[0] + $aPos[2] $aPos[3] = $aPos[1] + $aPos[3] If @error Then Return SetError(1, 0, 0) For $i = 1 To 4 DllStructSetData($tRect, $i, $aPos[$i - 1]) Next Return _WinAPI_PtInRect($tRect, $tPoint_MainGlobal) EndFunc ;==>HoveringOnHeader #EndRegion ListView tooltip funcs #Region context menu for split button Func _ContextMenu_ShowMenu($hWnd, $CtrlID, $nContextID, $n_dx = 0) ; Show a menu in a given GUI window which belongs to a given GUI ctrl Local $arPos, $x, $y Local $hMenu = GUICtrlGetHandle($nContextID) $arPos = ControlGetPos($hWnd, "", $CtrlID) $x = $arPos[0] + $n_dx $y = $arPos[1] + $arPos[3] _ContextMenu_ClientToScreen($hWnd, $x, $y) _ContextMenu_TrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ;==>_ContextMenu_ShowMenu Func _ContextMenu_ClientToScreen($hWnd, ByRef $x, ByRef $y) ; Convert the client (GUI) coordinates to screen (desktop) coordinates Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFunc ;==>_ContextMenu_ClientToScreen Func _ContextMenu_TrackPopupMenu($hWnd, $hMenu, $x, $y) ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ;==>_ContextMenu_TrackPopupMenu Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $wParam Local $tNMBHOTITEM = DllStructCreate("hwnd hWndFrom;int IDFrom;int Code;dword dwFlags", $lParam) Local $nNotifyCode = DllStructGetData($tNMBHOTITEM, "Code") Local $hCtrl = DllStructGetData($tNMBHOTITEM, "hWndFrom") Switch $nNotifyCode Case $BCN_DROPDOWN _ContextMenu_ShowMenu($hGUI, $gScript_Convert, $gScript_Convert_Menu) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY #EndRegion context menu for split button
    1 point
  4. _WinAPI_ShellGetFileInfo() ?
    1 point
  5. That means Your modem (or other connecting device) has reported an error. conect the modem manually and check that it works corretly. then try rasdial call again. Saludos
    1 point
  6. kylomas

    problem with variable

    NP, we've all experienced "you can't see the forest for the trees"...
    1 point
  7. Try this Code check the return. Global Const $RAS_MaxAreaCode = 10 Global Const $RAS_MaxPhoneNumber = 128 Global Const $RAS_MaxDeviceType = 16 Global Const $RAS_MaxDeviceName = 128 Global Const $RAS_MaxPadType = 32 Global Const $RAS_MaxX25Address = 200 Global Const $RAS_MaxFacilities = $RAS_MaxX25Address Global Const $RAS_MaxUserData = $RAS_MaxFacilities Global Const $RAS_MaxDnsSuffix = 256 Global Const $RAS_MaxEntryName = 256 Global Const $WM_RASDIALEVENT = 0xCCCD Global Const $RASCS_DONE = 0x2000 Global Const $WAIT_OBJECT_0 = 0 Global $hConection = 0 Global $tagRASCONNSTATUS = "dword dwSize;dword rasconnstate;wchar szDeviceType[" & $RAS_MaxDeviceType & "];wchar szDeviceName[" & $RAS_MaxDeviceName & "];" & _ "wchar szPhoneNumber[" & $RAS_MaxPhoneNumber & "];dword localEndPoint;byte[16];word[8];dword remoteEndPoint;byte[16];word[8];dword rasconnsubstate" Global Const $tagRASDIALPARAMS = "dword dwSize;wchar szEntryName[256];wchar szPhoneNumber[128];wchar szCallbackNumber[128];wchar szUserName[256];wchar szPassword[256];wchar szDomain[15];dword dwSubEntry;ULONG_PTR dwCallbackId;dword dwIfIndex" Local $tRASDIALPARAMS = DllStructCreate($tagRASDIALPARAMS) $tRASDIALPARAMS.dwSize = DllStructGetSize($tRASDIALPARAMS) DllStructSetData($tRASDIALPARAMS, "szEntryName", "HM-LINK") DllStructSetData($tRASDIALPARAMS, "szPhoneNumber", "") DllStructSetData($tRASDIALPARAMS, "szUserName", "") DllStructSetData($tRASDIALPARAMS, "szPassword", "") DllStructSetData($tRASDIALPARAMS, "szDomain", "") Local $FilePath=@AppDataDir & "\Microsoft\Network\Connections\Pbk\rasphone.pbk" Local $iRet = DllCall("Rasapi32.dll", "dword", "RasDialW", "ptr", 0,"wstr",$FilePath, "ptr", DllStructGetPtr($tRASDIALPARAMS), "dword", 0, "ptr", Null, "handle*", NULL) MsgBox(0,"",$iRet[0]) If $iRet[0] Then Local $Ret = DllCall("Rasapi32.dll", "dword", "RasGetErrorStringW", "uint", $iRet[0], "wstr", NULL, "dword", 256) ConsoleWrite( $Ret[2] & @CRLF) $hConection = $iRet[6] Else ConsoleWrite("Rasdial OK" & @CRLF) $hConection = $iRet[6] EndIf Saludos
    1 point
  8. kylomas

    problem with variable

    What is a "$" sign for $200, Alex...
    1 point
  9. UEZ

    GDIPlus Crashing

    See my comments: _GDIPlus_Startup() $fileA = @ScriptDir & "\images\file1.bmp" $hImageA = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\images\file1.bmp") ;<- this is a GDIPlus bitmap $hBitmapA = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImageA) ;<- this is a GDI bitmap! $pix = _GDIPlus_BitmapGetPixel($hBitmapA,5,5) ;<- _GDIPlus_BitmapGetPixel() can handle only GDIPlus bitmaps! consolewrite($pix) _GDIPlus_ImageDispose($hBitmapA) _GDIPlus_Shutdown() $pix = _GDIPlus_BitmapGetPixel($hImageA,5,5) should work. Br, UEZ
    1 point
  10. Kyan

    StringRegExp problem

    1) ^[^.][A-Za-z]+$ 2) ^[^0]d+$
    1 point
  11. I think you RASCONN structure should have 11 elements. Yours has 10. look the example above, also look this example. If you want can go first with the ANSI. if all is right, then pass it to unicode. Also: I think the last parameter of RasDial is not a pointer to a RASCONN structure. I think msdn says to a handle data type hrasconn. so should be so: Local $pRASCONN = DllStructGetPtr($tRASCONN,"hRasConn") or You can try as I saw some message above $msg = DllCall("Rasapi32.dll","DWORD","RasDial","ptr",0,"str",$phnbook,"struct*",$tTRASCREDENTIALS,"ptr",0,"hwnd", 0,"hwnd*",0) $hrasconn=$msg[6] Saludos
    1 point
×
×
  • Create New...