Sign in to follow this  
Followers 0
Mecrazycoder

Find the location of given file

8 posts in this topic

Hi Friends,

I am again posting this question in different manner.Is there any way to find the location(full path) of given file.Say for an example,i am giving iexplore.exe as input and output must be C:\Program Files\Internet Explorer.I used recursive but time consumption is high.

Tanx in advance.


[size="4"][font="Arial Narrow"][font="Garamond"]Attitude is a little thing that makes a big difference[/font][/font][/size][indent][/indent]

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Can't say anything about if this is following all best practices but it works on my XP and Vista machines.

So, enjoy. This works for all most installed applications.

$appLoc = _GetAppLocation("iexplore.exe")
MsgBox(0,"", $appLoc)


Func _GetAppLocation($app)
    $result = RegRead("HKEY_CLASSES_ROOT\Applications\" & $app & "\shell\open\command", "")
    $result = StringRegExpReplace($result, "%.", "")
    $result = StringReplace($result, """", "")
    Return $result
EndFunc
Edited by Manadar

Share this post


Link to post
Share on other sites

Try this one:

$sFile = "test.ini"  ; or any other filename WITHOUT a path
$aDrives = DriveGetDrive('ALL')

If IsArray($aDrives) Then
    For $i = 1 to $aDrives[0]
        ConsoleWrite("Searching " & $aDrives[$i] & @CRLF)
        _RecFileFinder($aDrives[$i], $sFile)
    Next
EndIf

Func _RecFileFinder($sDrive = "", $sFile = "")

    Local $asFolderList[3] = [1], $sCurrentPath, $hSearch, $sName, $fFolder

    ; Check parameters
    If $sDrive = "" Or $sFile = "" Then Return SetError(1, 0, 0)

    ; Ensure trailing \
    If StringRight($sDrive, 1) <> "\" Then $sDrive = $sDrive & "\"
    ; Add path to folder list
    $asFolderList[1] = $sDrive

    ; Search in listed folders
    While $asFolderList[0] > 0

        ; Set path to search
        $sCurrentPath = $asFolderList[$asFolderList[0]]
        ConsoleWrite("Searching: " & $sCurrentPath & @CRLF)
        ; Reduce folder array count
        $asFolderList[0] -= 1
        ; Get search handle
        $hSearch = FileFindFirstFile($sCurrentPath & "*")
        ; If folder empty move to next in list
        If $hSearch = -1 Then ContinueLoop

        ; Search folder
        While 1
            $sName = FileFindNextFile($hSearch)
            ; Check for end of folder
            If @error Then ExitLoop
            ; Check for subfolder
            ;$fFolder = @extended ; @extended set in 3.3.1.1 +  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            $fFolder = StringInStr(FileGetAttrib($sCurrentPath & $sName), "D") ; pre 3.3.1.1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

            ; Add subfolder to folder list
            If $fFolder Then
                ; Increase folder array count
                $asFolderList[0] += 1
                ; Double folder array size if too small (fewer ReDim needed)
                If UBound($asFolderList) <= $asFolderList[0] + 1 Then ReDim $asFolderList[UBound($asFolderList) * 2]
                ; Add subfolder to list
                $asFolderList[$asFolderList[0]] = $sCurrentPath & $sName & "\"
            EndIf

            ; Check filename against required value
            If Not $fFolder And $sName = $sFile Then

                ;This is where you can do what you want with the found files
                MsgBox(0, "Result", "Found " & $sCurrentPath & $sName)

            EndIf
        WEnd

        ; Close current search
        FileClose($hSearch)

    WEnd

    Return 1

EndFunc   ;==>_RecFileFinde

Share this post


Link to post
Share on other sites

Juvigy, he said "I used recursive but time consumption is high. ". I checked one of his other topics and that's where he tried what you are demonstrating right now.

Attention to detail is important. : )

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Yep i missed that he has used the same. But it is the only way to find all files.

I slightly remember there was a dll call that was possible that was using the windows search engine but i cant find it now.

Maybe DOS command like

dir c:\ /s /b | find "explorer"
?

Share this post


Link to post
Share on other sites

Tanx frendz for ur response


[size="4"][font="Arial Narrow"][font="Garamond"]Attitude is a little thing that makes a big difference[/font][/font][/size][indent][/indent]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

You can use a stack for searching instead of recursion. Problem is that you need to set the stack size in advance, not unless you know how to make a linked list implementation of a stack. (I don't. Know how to make a linked list in AutoIt, that is.)

The issue with using a stack is that if your stack is too small, you run out of space to add new search parameters. If it's too big, you waste allocated memory.

Global $RESULT_MAX = 0xFFF  ;Set to your preferred maximum number of results returned
Global $STACK_MAX = 0xFFF   ;Set to your preferred maximum number of elements in the stack
Global $STACK[$STACK_MAX]
$STACK[0] = 0

Func _Push($var)
    If $STACK[0] < $STACK_MAX - 1 Then
        $STACK[0] += 1
        $STACK[$STACK[0]] = $var
    Else
        Return 1
    EndIf
    Return 0
EndFunc

Func _Pop()
    If $STACK[0] > 0 Then
        $STACK[0] -= 1
        Return $STACK[$STACK[0] + 1]
    Else
        SetError(1)
    EndIf
    Return 0
EndFunc

;$path = the root path where the search is started
;$filter = the filter used by FileFindFirstFile and FileFindNextFile
;$exclude = the file attribute(s) excluded from the search
;$depth = the maximum recursion depth (# of subfolder levels from the root) for the search
;   -1 for search all subfolders
;   0 for search only root folder
;   n to search upto n subfolders deep
;Returns an array with [0] containing the number of returned results and [1] being the first result
;Sets @error to 1 if root path is invalid
Func _Search($path, $filter, $exclude, $depth)
    Local $current = @WorkingDir
    If FileChangeDir($path) == 1 Then
        If StringCompare(StringRight($path, 1), "\") <> 0 Then
            $path &= "\"
        EndIf
        Local $array[2] = [$path, 0]
        _Push($array)
        Local $result = _SearchUtil($filter, $exclude, $depth)
        FileChangeDir($current)
        Return $result
    Else
        SetError(1)
    EndIf
    FileChangeDir($current)
    Local $empty[2] = [0, 0]
    Return $empty
EndFunc

Func _SearchUtil($filter, $exclude, $depth)
    Local $result[$RESULT_MAX]
    Local $search, $fname, $attrib
    Local $array[2], $temp[2]
    $result[0] = 0
    While 1
        ;get top of stack
        $array = _Pop()
        If @error == 1 Then
            ExitLoop
        EndIf
        ;change directory
        FileChangeDir($array[0])
        ;search for matches in current directory
        $search = FileFindFirstFile($filter)
        While 1
            $fname = FileFindNextFile($search)
            If @error == 1 Then
                ExitLoop
            EndIf
            $attrib = FileGetAttrib($fname)
            If _IsIncluded($attrib, $exclude) Then
                $result[0] += 1
                $result[$result[0]] = $array[0] & $fname
            EndIf
        WEnd
        ;search subdirectory
        If $depth == -1 Or $array[1] < $depth Then
            $search = FileFindFirstFile("*")
            While 1
                $fname = FileFindNextFile($search)
                If @error == 1 Then
                    ExitLoop
                EndIf
                $attrib = FileGetAttrib($fname)
                If StringInStr($attrib, "D") <> 0 Then
                    If _IsIncluded($attrib, $exclude) Then
                        $temp[0] = $array[0]
                        $temp[1] = $array[1] + 1
                        _Push($temp)
                    EndIf
                EndIf
            WEnd
        EndIf
    WEnd
    Return $result
EndFunc

Func _IsIncluded($attrib, $exclude)
    For $i = 1 To StringLen($exclude)
        If StringInStr($attrib, StringMid($exclude, $i, 1)) <> 0 Then
            Return False
        EndIf
    Next
    Return True
EndFunc

It's a bit simplistic but just modify to taste.

As for the time, I'm not sure how long it would take if you don't limit your search, but I did notice, at least in Windows XP, is that only the initial search is the slowest one. After the first search, succeeding searches are faster. So, as a single use script, it would'nt be quick, but if it's used for multiple times in a single Windows login session, then it would be alright.

Edited by omikron48

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
Sign in to follow this  
Followers 0