Leaderboard
Popular Content
Showing content with the highest reputation on 03/25/2020 in all areas
-
I've had this one rolling around my brain for a while now. And while I can't take credit for much of anything at this point since it's just implementation, here's a framework for Time-based One-Time Password authentication, ie Google Authenticator. I've added links in all the places where I've harvested code. I'm planning on building this into an actual authenticator app, so this is just step one. As always, thanks to everyone whose code contributed. _GAuth.au3 #include-once #include <_HMAC.au3> #include <Date.au3> ;; http://tools.ietf.org/html/rfc6238 Func _GenerateTOTP($key, $keyIsBase32 = True, $time = Default, $period = 30, $digits = 6) Local $DIGITS_POWER[9] = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000] ; time is some number of seconds If $time = Default Then $time = _GetUnixTimeUTC() $time = StringFormat("%016X", Floor($time / $period)) If $keyIsBase32 Then $key = _Base32ToHex($key, True) ; return binary Else $key = StringToBinary($key) EndIf ; HMAC function expects binary arguments Local $hash = _HMAC_SHA1($key, Binary("0x" & $time)) Local $offset = BitAND(BinaryMid($hash, BinaryLen($hash), 1), 0xf) Local $otp = BitOR(BitShift(BitAND(BinaryMid($hash, $offset + 1, 1), 0x7f), -24), _ BitShift(BitAND(BinaryMid($hash, $offset + 2, 1), 0xff), -16), _ BitShift(BitAND(BinaryMid($hash, $offset + 3, 1), 0xff), -8), _ BitAND(BinaryMid($hash, $offset + 4, 1), 0xff) _ ) $otp = Mod($otp, $DIGITS_POWER[$digits]) Return StringFormat("%0" & $digits & "i", $otp) EndFunc ;; http://www.autoitscript.com/forum/topic/153617-seconds-since-epoch-aka-unix-timestamp/ Func _GetUnixTimeUTC() ; returns number of seconds since EPOCH in UTC Local $aSysTimeInfo = _Date_Time_GetTimeZoneInformation() Local $utcTime = "" Local $sDate = _NowCalc() If $aSysTimeInfo[0] = 2 Then $utcTime = _DateAdd('n', $aSysTimeInfo[1] + $aSysTimeInfo[7], $sDate) Else $utcTime = _DateAdd('n', $aSysTimeInfo[1], $sDate) EndIf Return _DateDiff('s', "1970/01/01 00:00:00", $utcTime) EndFunc ;; http://tomeko.net/online_tools/base32.php?lang=en Func _Base32ToHex($sInput, $returnBinary = False) $sInput = StringRegExpReplace(StringUpper($sInput), "[^A-Z2-7]", "") Local $key = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" Local $buffer = 0, $bitsLeft = 0, $i = 0, $count = 0, $output = "", $val While $i < StringLen($sInput) $val = StringInStr($key, StringMid($sInput, $i + 1, 1)) - 1 ; StringInStr returns 1 as 1st position If $val >=0 And $val < 32 Then $buffer = BitOR(BitShift($buffer, -5), $val) $bitsLeft += 5 If $bitsLeft >= 8 Then $output &= Chr(BitAND(BitShift($buffer, $bitsLeft - 8), 0xFF)) $bitsLeft -= 8 EndIf EndIf $i += 1 WEnd If $bitsLeft > 0 Then $buffer = BitShift($buffer, -5) $output &= Chr(BitAND(BitShift($buffer, $bitsLeft - 3), 0xFF)) EndIf If $returnBinary Then Return StringToBinary($output) Else Return $output EndIf EndFunc #cs Alternate base32 to hex functions Func _b32toh($input) $input = StringRegExpReplace(StringUpper($input), "[^A-Z2-7]", "") Local $ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" Local $bits = "", $hex = "", $val, $i For $i = 0 To StringLen($input) - 1 $val = StringInStr($ch, StringMid($input, $i + 1, 1)) - 1 $bits &= StringFormat("%05s", _itob($val)) Next $i = 0 Local $chunk While ($i + 4) <= StringLen($bits) $chunk = StringMid($bits, $i + 1, 4) $hex &= StringFormat("%X", _btoi($chunk)) $i += 4 WEnd Return $hex EndFunc ; int to binary (0's and 1's) string Func _itob($int) Local $o = "" While $int $o = BitAND($int, 1) & $o $int = BitShift($int, 1) WEnd Return $o EndFunc ; binary (0's and 1's) string to int Func _btoi($b) Local $p = 0, $o = 0 For $i = StringLen($b) To 1 Step -1 $o += (2 ^ $p) * Number(StringMid($b, $i, 1)) $p += 1 Next Return $o EndFunc #ce Func _TOTPTestVectors() #cs Test vectors operate in HOTP mode. The test token shared secret uses the ASCII string value "12345678901234567890". With Time Step X = 30, and the Unix epoch as the initial value to count time steps, where T0 = 0, the TOTP algorithm will display the following values for specified modes and timestamps. +-------------+--------------+------------------+----------+--------+ | Time (sec) | UTC Time | Value of T (hex) | TOTP | Mode | +-------------+--------------+------------------+----------+--------+ | 59 | 1970-01-01 | 0000000000000001 | 94287082 | SHA1 | | | 00:00:59 | | | | | 1111111109 | 2005-03-18 | 00000000023523EC | 07081804 | SHA1 | | | 01:58:29 | | | | | 1111111111 | 2005-03-18 | 00000000023523ED | 14050471 | SHA1 | | | 01:58:31 | | | | | 1234567890 | 2009-02-13 | 000000000273EF07 | 89005924 | SHA1 | | | 23:31:30 | | | | | 2000000000 | 2033-05-18 | 0000000003F940AA | 69279037 | SHA1 | | | 03:33:20 | | | | | 20000000000 | 2603-10-11 | 0000000027BC86AA | 65353130 | SHA1 | | | 11:33:20 | | | | +-------------+--------------+------------------+----------+--------+ #ce Local $times[6] = [59, 1111111109, 1111111111, 1234567890, 2000000000, 20000000000] For $i = 0 To 5 ConsoleWrite(StringFormat("%016X", Floor($times[$i] / 30)) & " : " & _ _GenerateTOTP("12345678901234567890", False, $times[$i], 30, 8) & @CRLF) Next EndFunc _HMAC.au3 #include-once #include <Crypt.au3> ;; http://www.autoitscript.com/forum/topic/145556-solved-hmac-sha1/?p=1028830 Func _HMAC_SHA1($key, $message) If Not IsBinary($key) Then $key = Binary($key) If Not IsBinary($message) Then $message = Binary($message) Local $blocksize = 64 Local $a_opad[$blocksize], $a_ipad[$blocksize] Local Const $oconst = 0x5C, $iconst = 0x36 Local $opad = Binary(''), $ipad = Binary('') If BinaryLen($key) > $blocksize Then $key = _Crypt_HashData($key, $CALG_SHA1) For $i = 1 To BinaryLen($key) $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1)) $a_opad[$i-1] = Number(BinaryMid($key, $i, 1)) Next For $i = 0 To $blocksize - 1 $a_opad[$i] = BitXOR($a_opad[$i], $oconst) $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst) Next For $i = 0 To $blocksize - 1 $ipad &= Binary('0x' & Hex($a_ipad[$i], 2)) $opad &= Binary('0x' & Hex($a_opad[$i], 2)) Next Return _Crypt_HashData($opad & _Crypt_HashData($ipad & $message, $CALG_SHA1), $CALG_SHA1) EndFunc Func _HMAC_MD5($key, $message) If Not IsBinary($key) Then $key = Binary($key) If Not IsBinary($message) Then $message = Binary($message) Local $blocksize = 64 Local $a_opad[$blocksize], $a_ipad[$blocksize] Local Const $oconst = 0x5C, $iconst = 0x36 Local $opad = Binary(''), $ipad = Binary('') If BinaryLen($key) > $blocksize Then $key = _Crypt_HashData($key, $CALG_MD5) For $i = 1 To BinaryLen($key) $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1)) $a_opad[$i-1] = Number(BinaryMid($key, $i, 1)) Next For $i = 0 To $blocksize - 1 $a_opad[$i] = BitXOR($a_opad[$i], $oconst) $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst) Next For $i = 0 To $blocksize - 1 $ipad &= Binary('0x' & Hex($a_ipad[$i], 2)) $opad &= Binary('0x' & Hex($a_opad[$i], 2)) Next Return _Crypt_HashData($opad & _Crypt_HashData($ipad & $message, $CALG_MD5), $CALG_MD5) EndFunc Example: Use the test vectors function to test HOTP mode, or visit http://gauth.apps.gbraad.nl/ for a live test site. The default account uses "JBSWY3DPEHPK3PXP" as the key ( https://code.google.com/p/google-authenticator/wiki/KeyUriFormat ). ConsoleWrite(_GenerateTOTP("JBSWY3DPEHPK3PXP") & @CRLF)1 point
-
This is a question which gets asked quite a bit >> How to add my program to the Startup Folder? Or How can I make my program run when the PC starts? So for those who want to call a simple Function e.g. _StartupFolder_Install() this UDF is for you. UDF: #include-once ; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7 ; #INDEX# ======================================================================================================================= ; Title .........: _Startup ; AutoIt Version : v3.3.10.0 or higher ; Language ......: English ; Description ...: Create startup entries in the startup folder or registry. The registry entries can be Run all the time (Run registry entry) or only once (RunOnce registry entry.) ; Note ..........: ; Author(s) .....: guinness ; Remarks .......: Special thanks to KaFu for EnumRegKeys2Array() which I used as inspiration for enumerating the Registry Keys. ; =============================================================================================================================== ; #INCLUDES# ==================================================================================================================== #include <StringConstants.au3> ; #GLOBAL VARIABLES# ============================================================================================================ Global Enum $STARTUP_RUN = 0, $STARTUP_RUNONCE, $STARTUP_RUNONCEEX ; #CURRENT# ===================================================================================================================== ; _StartupFolder_Exists: Checks if an entry exits in the 'All Users/Current Users' startup folder. ; _StartupFolder_Install: Creates an entry in the 'All Users/Current Users' startup folder. ; _StartupFolder_Uninstall: Deletes an entry in the 'All Users/Current Users' startup folder. ; _StartupRegistry_Exists: Checks if an entry exits in the 'All Users/Current Users' registry. ; _StartupRegistry_Install: Creates an entry in the 'All Users/Current Users' registry. ; _StartupRegistry_Uninstall: Deletes the entry in the 'All Users/Current Users' registry. ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#============================================================================================================ ; See below. ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupFolder_Exists ; Description ...: Checks if an entry exits in the 'All Users/Current Users' startup folder. ; Syntax ........: _StartupFolder_Exists([$sName = @ScriptName[, $bAllUsers = False]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $bAllUsers - [optional] Add to Current Users (False) or All Users (True) Default is False. ; Return values .: Success - True ; Failure - False ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupFolder_Exists($sName = @ScriptName, $bAllUsers = False) Local $sFilePath = Default __Startup_Format($sName, $sFilePath) Return FileExists(__StartupFolder_Location($bAllUsers) & '\' & $sName & '.lnk') EndFunc ;==>_StartupFolder_Exists ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupFolder_Install ; Description ...: Creates an entry in the 'All Users/Current Users' startup folder. ; Syntax ........: _StartupFolder_Install([$sName = @ScriptName[, $sFilePath = @ScriptFullPath[, $sCommandline = ''[, ; $bAllUsers = False]]]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $sFilePath - [optional] Location of the program executable. Default is @ScriptFullPath. ; $sCommandline - [optional] Commandline arguments to be passed to the application. Default is ''. ; $bAllUsers - [optional] Add to Current Users (False) or All Users (True) Default is False. ; Return values .: Success - True ; Failure - False & sets @error to non-zero ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupFolder_Install($sName = @ScriptName, $sFilePath = @ScriptFullPath, $sCommandline = '', $bAllUsers = False) Return __StartupFolder_Uninstall(True, $sName, $sFilePath, $sCommandline, $bAllUsers) EndFunc ;==>_StartupFolder_Install ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupFolder_Uninstall ; Description ...: Deletes an entry in the 'All Users/Current Users' startup folder. ; Syntax ........: _StartupFolder_Uninstall([$sName = @ScriptName[, $sFilePath = @ScriptFullPath[, $bAllUsers = False]]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $sFilePath - [optional] Location of the program executable. Default is @ScriptFullPath. ; $bAllUsers - [optional] Was it added to Current Users (False) or All Users (True) Default is False. ; Return values .: Success - True ; Failure - False & sets @error to non-zero ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupFolder_Uninstall($sName = @ScriptName, $sFilePath = @ScriptFullPath, $bAllUsers = False) Return __StartupFolder_Uninstall(False, $sName, $sFilePath, Default, $bAllUsers) EndFunc ;==>_StartupFolder_Uninstall ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupRegistry_Exists ; Description ...:Checks if an entry exits in the 'All Users/Current Users' registry. ; Syntax ........: _StartupRegistry_Exists([$sName = @ScriptName[, $bAllUsers = False[, $iRunOnce = $STARTUP_RUN]]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $bAllUsers - [optional] Add to Current Users (False) or All Users (True) Default is False. ; $iRunOnce - [optional] Always run at system startup $STARTUP_RUN (0), run only once before explorer is started $STARTUP_RUNONCE (1) ; or run only once after explorer is started $STARTUP_RUNONCEEX (2). Default is $STARTUP_RUN (0). ; Return values .: Success - True ; Failure - False ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupRegistry_Exists($sName = @ScriptName, $bAllUsers = False, $iRunOnce = $STARTUP_RUN) Local $sFilePath = Default __Startup_Format($sName, $sFilePath) RegRead(__StartupRegistry_Location($bAllUsers, $iRunOnce) & '\', $sName) Return @error = 0 EndFunc ;==>_StartupRegistry_Exists ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupRegistry_Install ; Description ...: Creates an entry in the 'All Users/Current Users' registry. ; Syntax ........: _StartupRegistry_Install([$sName = @ScriptName[, $sFilePath = @ScriptFullPath[, $sCommandline = ''[, ; $bAllUsers = False[, $iRunOnce = $STARTUP_RUN]]]]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $sFilePath - [optional] Location of the program executable. Default is @ScriptFullPath. ; $sCommandline - [optional] Commandline arguments to be passed to the application. Default is ''. ; $bAllUsers - [optional] Add to Current Users (False) or All Users (True) Default is False. ; $iRunOnce - [optional] Always run at system startup $STARTUP_RUN (0), run only once before explorer is started $STARTUP_RUNONCE (1) ; or run only once after explorer is started $STARTUP_RUNONCEEX (2). Default is $STARTUP_RUN (0). ; Return values .: Success - True ; Failure - False & sets @error to non-zero ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupRegistry_Install($sName = @ScriptName, $sFilePath = @ScriptFullPath, $sCommandline = '', $bAllUsers = False, $iRunOnce = $STARTUP_RUN) Return __StartupRegistry_Uninstall(True, $sName, $sFilePath, $sCommandline, $bAllUsers, $iRunOnce) EndFunc ;==>_StartupRegistry_Install ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StartupRegistry_Uninstall ; Description ...: Deletes the entry in the 'All Users/Current Users' registry. ; Syntax ........: _StartupRegistry_Uninstall([$sName = @ScriptName[, $sFilePath = @ScriptFullPath[, $bAllUsers = False[, ; $iRunOnce = Default]]]]) ; Parameters ....: $sName - [optional] Name of the program. Default is @ScriptName. ; $sFilePath - [optional] Location of the program executable. Default is @ScriptFullPath. ; $bAllUsers - [optional] Was it added to the current users (0) or all users (1). Default is 0. ; $iRunOnce - [optional] Was it run at system startup $STARTUP_RUN (0), run only once before explorer is started $STARTUP_RUNONCE (1) ; or run only once after explorer is started $STARTUP_RUNONCEEX (2). Default is $STARTUP_RUN (0). ; Return values .: Success - True ; Failure - False & sets @error to non-zero ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _StartupRegistry_Uninstall($sName = @ScriptName, $sFilePath = @ScriptFullPath, $bAllUsers = False, $iRunOnce = $STARTUP_RUN) Return __StartupRegistry_Uninstall(False, $sName, $sFilePath, Default, $bAllUsers, $iRunOnce) EndFunc ;==>_StartupRegistry_Uninstall ; #INTERNAL_USE_ONLY#============================================================================================================ Func __Startup_Format(ByRef $sName, ByRef $sFilePath) If $sFilePath = Default Then $sFilePath = @ScriptFullPath EndIf If $sName = Default Then $sName = @ScriptName EndIf $sName = StringRegExpReplace($sName, '\.[^.\\/]*$', '') ; Remove extension. Return Not (StringStripWS($sName, $STR_STRIPALL) == '') And FileExists($sFilePath) EndFunc ;==>__Startup_Format Func __StartupFolder_Location($bAllUsers) Return $bAllUsers ? @StartupCommonDir : @StartupDir EndFunc ;==>__StartupFolder_Location Func __StartupFolder_Uninstall($bIsInstall, $sName, $sFilePath, $sCommandline, $bAllUsers) If Not __Startup_Format($sName, $sFilePath) Then Return SetError(1, 0, False) ; $STARTUP_ERROR_EXISTS EndIf If $bAllUsers = Default Then $bAllUsers = False EndIf If $sCommandline = Default Then $sCommandline = '' EndIf Local Const $sStartup = __StartupFolder_Location($bAllUsers) Local Const $hSearch = FileFindFirstFile($sStartup & '\' & '*.lnk') Local $vReturn = 0 If $hSearch > -1 Then Local Const $iStringLen = StringLen($sName) Local $aFileGetShortcut = 0, _ $sFileName = '' While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop EndIf If StringLeft($sFileName, $iStringLen) = $sName Then $aFileGetShortcut = FileGetShortcut($sStartup & '\' & $sFileName) If @error Then ContinueLoop EndIf If $aFileGetShortcut[0] = $sFilePath Then $vReturn += FileDelete($sStartup & '\' & $sFileName) EndIf EndIf WEnd FileClose($hSearch) ElseIf Not $bIsInstall Then Return SetError(2, 0, False) ; $STARTUP_ERROR_EMPTY EndIf If $bIsInstall Then $vReturn = FileCreateShortcut($sFilePath, $sStartup & '\' & $sName & '.lnk', $sStartup, $sCommandline) > 0 Else $vReturn = $vReturn > 0 EndIf Return $vReturn EndFunc ;==>__StartupFolder_Uninstall Func __StartupRegistry_Location($bAllUsers, $iRunOnce) If $iRunOnce = Default Then $iRunOnce = $STARTUP_RUN EndIf Local $sRunOnce = '' Switch $iRunOnce Case $STARTUP_RUNONCE $sRunOnce = 'Once' Case $STARTUP_RUNONCEEX $sRunOnce = 'OnceEx' Case Else $sRunOnce = '' EndSwitch Return ($bAllUsers ? 'HKEY_LOCAL_MACHINE' : 'HKEY_CURRENT_USER') & _ ((@OSArch = 'X64') ? '64' : '') & '\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' & $sRunOnce EndFunc ;==>__StartupRegistry_Location Func __StartupRegistry_Uninstall($bIsInstall, $sName, $sFilePath, $sCommandline, $bAllUsers, $iRunOnce) If Not __Startup_Format($sName, $sFilePath) Then Return SetError(1, 0, False) ; $STARTUP_ERROR_EXISTS EndIf If $bAllUsers = Default Then $bAllUsers = False EndIf If $sCommandline = Default Then $sCommandline = '' EndIf Local Const $sRegistryKey = __StartupRegistry_Location($bAllUsers, $iRunOnce) Local $iInstance = 1, _ $sRegistryName = '', _ $vReturn = 0 While 1 $sRegistryName = RegEnumVal($sRegistryKey & '\', $iInstance) If @error Then ExitLoop EndIf If ($sRegistryName = $sName) And StringInStr(RegRead($sRegistryKey & '\', $sRegistryName), $sFilePath, $STR_NOCASESENSEBASIC) Then $vReturn += RegDelete($sRegistryKey & '\', $sName) EndIf $iInstance += 1 WEnd If $bIsInstall Then $vReturn = RegWrite($sRegistryKey & '\', $sName, 'REG_SZ', $sFilePath & ' ' & $sCommandline) > 0 Else $vReturn = $vReturn > 0 EndIf Return $vReturn EndFunc ;==>__StartupRegistry_UninstallExample 1: #include '_Startup.au3' Example() Func Example() _StartupFolder_Install() ; Add the running EXE to the Current Users startup folder. ShellExecute(@StartupDir & '\') Sleep(5000) _StartupFolder_Uninstall() ; Remove the running EXE from the Current Users startup folder. EndFunc ;==>ExampleExample 2: #include '_Startup.au3' Example() Func Example() _StartupRegistry_Install() ; Add the running EXE to the Current Users Run registry key. Sleep(5000) _StartupRegistry_Uninstall() ; Remove the running EXE from the Current Users Run registry key. EndFunc ;==>ExampleAll of the above has been included in a ZIP file. Startup.zipPrevious: 1447+ downloads.1 point
-
Must be the reason why you are loosing the object. Like I said run your script x64, and you should be good...1 point
-
If you loose $oIE object, it means that you have another problem on your hands. I have experienced this when running IE UDF in x86 (especially if I was extracting tables into arrays). After I changed to run in x64 the problem disappeared. The behavior of your script seems very similar of what I experienced. It runs fine for a certain number of loops and suddenly I get object errors. Try this first then if that didn't solve your issue, post a more substantial part of your script.1 point
-
1 point
-
You could add COM error handling or maybe check if IsObj($oIE)1 point
-
Turning off automatic Windows Time Update service was the solution. It can be done by either of following 2 methods: 1. Turn off "Settings - Time and language - Date and time - Set time automatically" 2. Click off "Control panel - Date and time - Internet time - Synchronize with an internet time server" Increasing the SpecialPollInterval value in the registry didn't work. After turning off Windows Time Update, _Date_Time_SetSystemTimeAdjustment remained effective for a full day for the first time since I started to use this code. Thank you, @faustf and @TheXman, for your hints.1 point
-
Forum Rules You can read about forum rules here. Announcements and site news Additional information about forum you can read here. Forum etiquette Here you can read about a proper forum etiquette.1 point
-
Take your time as I'll be doing this on the weekend.1 point
-
You could immediately split the path using "." as delimiter. $split = StringSplit($path, ".") $ext = $split[$split[0]]1 point
-
help file under section: 'Running the 32-bit version of AutoIt on a x64 System' DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 1)1 point
-
With the help of Blindwig's code which evilertoaster linked to above, this is what I hashed out, You might never need many of the options in the functions depending on what you're trying to do. But here goes: CODE$path = "C:\mydirectory" $FileArray = _FileFindAllR($path, '*.dwg') For $i = 1 To $FileArray[0] ShellExecute($FileArray[$i]) Next ;=============================================================================== ; ; Function Name: _FileFindAllR ; Description: Returns a recursive list of files ; Parameter(s): $Path = root path to begin the listing from ; $Mask = file mask to match ; $AttribFilter = File Attributes to filter files through. See _FileFilterAttrib for details ; $ProgressTitle = A title to put on a progress window. Empty String = no progress window ; Requirement(s): $Path is an existing directory ; Return Value(s): A 1-based array containing the full path of all found files ; Author(s): Mike Ratzlaff <mike@ratzlaff.org> ; Revision: 20050622A ; ;=============================================================================== ; ;Returns a recursive list of files under $Path, matching $Mask, and filtered through $AttribFilter Func _FileFindAllR($Path, $Mask='*', $AttribFilter='dhs', $ProgressTitle = @ScriptName) Dim $i, $aDirList = _FileGetTreeList($Path, $ProgressTitle), $FileList[@extended + 1] If $ProgressTitle <> '' Then ProgressOn($ProgressTitle, 'Scanning files...', '', -1, -1, 16) For $i = 1 to $aDirList[0] If $ProgressTitle <> '' Then ProgressSet($i * 100 / $aDirList[0], $aDirList[$i]) __FileFindAllR($FileList, $aDirList[$i], $Mask, $AttribFilter) Next If $ProgressTitle <> '' Then ProgressOff() ReDim $FileList[$FileList[0]+1] Return $FileList EndFunc Func __FileFindAllR(ByRef $aFileList, $Path, $Mask, $AttribFilter) Dim $hndSearch_Files $hndSearch_Files = FileFindFirstFile($Path & '\' & $Mask) If $hndSearch_Files <> -1 Then $sFileName = FileFindNextFile($hndSearch_Files) While Not @error If _FileFilterAttrib($Path & '\' & $sFileName, $AttribFilter) And $sFileName <> '.' And $sFileName <> '..' Then $aFileList[0] = $aFileList[0] + 1 $aFileList[$aFileList[0]] = $Path & '\' & $sFileName EndIf $sFileName = FileFindNextFile($hndSearch_Files) WEnd FileClose($hndSearch_Files) EndIf EndFunc Func _FileFilterAttrib($FileName, $Attrib) Dim $Return=0, $FileAttrib, $i, $ch If FileExists($FileName) Then $Return=-1 $FileAttrib = FileGetAttrib($FileName) For $i = 1 to StringLen($Attrib) $ch = StringMid($Attrib,$i,1) If StringIsUpper($ch) Then ;This attribute must be on the list If not StringInStr($FileAttrib, $ch) then $Return = 0 Else ;This attribute must not be on the list If StringInStr($FileAttrib, StringUpper($ch)) then $Return = 0 EndIf Next EndIf Return $Return EndFunc ;=============================================================================== ; ; Function Name: _FileGetTreeList ; Description: Returns a recursive list of directories ; Parameter(s): $Path = root path to begin the listing from ; $ProgressTitle = A title to put on a progress window. Empty String = no progress window ; Requirement(s): $Path is an existing directory ; Return Value(s): A 1-based array containing the full path of all found directories ; Note: Upon return, @Extended will contain a count of files (non-folders) found while searching for folders ; Author(s): Mike Ratzlaff <mike@ratzlaff.org> ; Revision: 20050622A ; ;=============================================================================== ; Func _FileGetTreeList($Path, $ProgressTitle = @ScriptName) Dim $aDirList[100], $TotalFiles = 0 If $ProgressTitle <> '' Then ProgressOn($ProgressTitle, 'Scanning directories...', '', -1, -1, 16) If _FileIsDir($Path) Then $TotalFiles = __FileGetTreeList($aDirList, $Path, $ProgressTitle) EndIf If $ProgressTitle <> '' Then ProgressOff() SetExtended($TotalFiles) ReDim $aDirList[$aDirList[0]+1] Return $aDirList EndFunc Func __FileGetTreeList(ByRef $aDirList, $Path, $ProgressTitle) Dim $hndSearch_Dirs, $FileCount If $ProgressTitle <> '' Then ProgressSet(random(99), $Path) ;Add the current directory on to the list $aDirList[0] = $aDirList[0] + 1 If $aDirList[0] > UBound($aDirList) - 1 Then ReDim $aDirList[$aDirList[0] + 20] $aDirList[$aDirList[0]] = $Path ;Scan for more directories $hndSearch_Dirs = FileFindFirstFile($Path & '\*') If $hndSearch_Dirs <> -1 Then $sFileName = FileFindNextFile($hndSearch_Dirs) While Not @error If _FileIsDir($Path & '\' & $sFileName) Then ;Recurse into the directory, if it's not a special directory If $sFileName <> '.' And $sFileName <> '..' Then $FileCount = $FileCount + __FileGetTreeList($aDirList, $Path & '\' & $sFileName, $ProgressTitle) EndIf Else ;Add to the filecount $FileCount = $FileCount + 1 EndIf $sFileName = FileFindNextFile($hndSearch_Dirs) WEnd EndIf FileClose($hndSearch_Dirs) Return $FileCount EndFunc ;=============================================================================== ; ; Function Name: _FileIsDir ; Description: Returns true or false weather given file is a directory or not ; Parameter(s): $Path ; Requirement(s): ; Return Value(s): 0 = not a directory or does not exist, 1 = file exists and is a directory ; Author(s): Mike Ratzlaff <mike@ratzlaff.org> ; Revision: 20050623A ; ;=============================================================================== ; Func _FileIsDir($Path) ;This function checkes to see if $FileName exists and if it is a Directory If StringInStr(FileGetAttrib($Path),'D') Then Return 1 Return 0 EndFunc1 point