Jump to content

Recommended Posts

Posted (edited)

I imagine someone's done this before, but I couldn't find it. I was trying to find a program without searching through lots of folders and attempted to use multiple wildcards, when I realized it wasn't possible.

Specifically, I was trying to find Adobe Acrobat, but it's located in different places depending on the computer... so this works to find it now: WildcardSearch("C:\Program Files*\Adobe\*\*\Acrobat.exe") It can be in either Program Files directory with \Adobe\<AcobatVersion>\Acrobat\Acrobat.exe and the Acrobat version varies. Ugh :)

(Known) Restrictions:

  • Wildcards are only supported at the end ("C:\Program Files*\" matches "C:\Program Files\" and "C:\Program Files (x86)\") Fixed!
  • Wildcards cannot represent backslashes, so you have to know the level of the file
  • Only supports asterisks
#include <Array.au3>    ; Only for _ArrayDisplay

_ArrayDisplay(WildcardSearch("U:\*\1\*\3\*\5\*\7\*\9\"), "Search Results...")
_ArrayDisplay(WildcardSearch("U:\*\1\*\3\*\5\*\7\*\9\*"), "Search Results...")
_ArrayDisplay(WildcardSearch("U:\*\1\*\3\*\5\*\7\*\*9*\*"), "Search Results...")

Func _Wildcard_Search($sSearch)

    Local $aFolders = StringSplit($sSearch, "\")
    Local $tempOptions[0], $aNewOptions[0]
    Local $aOptions[1]
    ; For each wildcard (minus the last one)
    For $i = 1 To UBound($aFolders) - 1
        ; For each option
        For $z = 0 To UBound($aOptions) - 1
            ; If there is a wildcard
            If StringInStr($aFolders[$i], "*") > 0 Then
                ; Search with the added section
                $aNewOptions = __SearchToArray($aOptions[$z] & $aFolders[$i])
                ; If the search completed then
                If Not @error Then __FastArrayAdd($tempOptions, $aNewOptions)
                ; Keep it if it exists
                __FileAddExists($tempOptions, $aOptions[$z] & $aFolders[$i])
        ; Get all the new options (old options will be missing pieces, so drop them)
        $aOptions = $tempOptions
        ; Clear the temp options
        Dim $tempOptions[0]
    Return $aOptions
EndFunc   ;==>_Wildcard_Search

; Returns array* of items, error 1 if search failed, error 2 if empty folder
Func __SearchToArray($sSearch)

    ; Get the base folder: Everything to the left of the last '\'
    Local $sBase = StringLeft($sSearch, StringInStr($sSearch, "\", 0, -1))
    ; Remove the base from the search
    $sSearch = StringReplace($sSearch, $sBase, "")

    Local $iErr = 0, $aResults[0]
    ; Search for it
    Local $hSearch = FileFindFirstFile($sBase & $sSearch)
    ; If the search failed
    If $hSearch = -1 Then
        $iErr = 1 + @error ; FileFindFirstFile Returns 1 with an empty folder
        ; Get the first file/dir
        Local $sResult = FileFindNextFile($hSearch)
        ; For each file found
        While $sResult <> ""
            __FileAddExists($aResults, $sBase & $sResult)
            ; Get the next file/dir
            $sResult = FileFindNextFile($hSearch)
    ; Close the search
    Return SetError($iErr, 0, $aResults)
EndFunc   ;==>__SearchToArray

; Adds a single item or an array to the end of an array (1D only)
Func __FastArrayAdd(ByRef $aArray, $vItem)
    Local $iSize = UBound($aArray)
    If IsArray($vItem) Then
        ; Resize the array
        ReDim $aArray[$iSize + UBound($vItem)]
        ; Add each item
        For $i = 0 To UBound($vItem) - 1
            $aArray[$iSize + $i] = $vItem[$i]
        ; Not array, resize and add to end
        ReDim $aArray[$iSize + 1]
        $aArray[$iSize] = $vItem
EndFunc   ;==>__FastArrayAdd

; Adds the file/directory to the list (All directories are appended with \'s)
Func __FileAddExists(ByRef $aResults, $sPath)
    ; If it exists
    If FileExists($sPath) Then
        ; If it's a file
        If StringInStr(FileGetAttrib($sPath), "D") = 0 Then
            __FastArrayAdd($aResults, $sPath)
            __FastArrayAdd($aResults, $sPath & "\")
EndFunc   ;==>__FileAddExists

Edit: Now I see that the 'start' will find the program for me. Welp.

Edit 2: Support for asterisks anywhere!

Edited by seadoggie01

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...