Jump to content

Recommended Posts

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.


My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...