Mecrazycoder Posted September 7, 2009 Share Posted September 7, 2009 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] Link to comment Share on other sites More sharing options...
jvanegmond Posted September 7, 2009 Share Posted September 7, 2009 (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 September 7, 2009 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
Juvigy Posted September 7, 2009 Share Posted September 7, 2009 Try this one: expandcollapse popup$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 Link to comment Share on other sites More sharing options...
jvanegmond Posted September 7, 2009 Share Posted September 7, 2009 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. : ) github.com/jvanegmond Link to comment Share on other sites More sharing options...
Yashied Posted September 7, 2009 Share Posted September 7, 2009 Seems the best way possible recursion. The question is how best to search (algorithm). You can search for such levels: first, all the root folders, then in their sub-folders, etc. My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
Juvigy Posted September 7, 2009 Share Posted September 7, 2009 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" ? Link to comment Share on other sites More sharing options...
Mecrazycoder Posted September 8, 2009 Author Share Posted September 8, 2009 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] Link to comment Share on other sites More sharing options...
omikron48 Posted September 8, 2009 Share Posted September 8, 2009 (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. expandcollapse popupGlobal $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 September 8, 2009 by omikron48 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now