Jump to content

[BATCH] Search file in all drives - Script help needed


Recommended Posts

HI,

I try to do a little script that would search in all drives for a specific file but i had no luck to get this script to work. Anyone here that could help me out with this or has a better script idea? :)

SETLOCAL EnableDelayedExpansionSET FindFile=test.cmdFOR /F %%a IN ('MOUNTVOL^|FINDSTR [A-Z]:\\') do (  FOR /F "tokens=*" %%b in ('DIR /B /S "%%a%FindFile%" 2^>nul') do (  SET "FoundFile=%%b" & GOTO FOUND  ))ECHO ERROR: File not found.PAUSEEXIT:FOUNDECHO File found in "%FoundFile%".ENDLOCALPAUSEEXIT















Edited by Mike88
Link to comment
Share on other sites


Using your code as a beginning point, here is a START at a solution:
 

@ECHO OFF & SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONSET FindFile=test.cmdSET FoundFile=NopeFOR /F %%a IN ('MOUNTVOL^|FINDSTR [A-Z]:\\') do (  CALL :IsItThere "%%a" %FindFile% FoundFile  IF "!FoundFile!" NEQ "Nope" GOTO :FOUND  ))ECHO ERROR: "%FindFile%" not found.PAUSEEXIT /b:FOUNDECHO File "%FindFile%" found in "%FoundFile%".ENDLOCALPAUSEEXIT /b :IsItThereSETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONSET Result=NopeIF EXIST "%~dp1%2" ((SET "Result=%~dp1")&GOTO :DONE)FOR /F "tokens=*" %%G IN ('dir /B /AD "%~dp1"') DO (  CALL :IsItThere "%%G" %2 Result  IF "!Result!" NEQ "Nope" GOTO :DONE):DONEENDLOCAL&(SET %3=%Result%)&EXIT /B 0

 
It has only been very minimally tested.  You will need to ensure that the cases of all valid possible path and file names are accounted for such as spaces and other troublesome characters such as ' and ) etc.  The code does not deal with possibilities such as MOUNTVOL returning a drive letter for a CD or DVD drive that does not have a disc in it and other annoyances.  Also, for a system with many terabytes of files this is likely to take quite awhile.  But as I said, it's a starting point.
 
Cheers and Regards

Link to comment
Share on other sites

The script in the 1st post has been tested here as working in Windows 7 X64. I do not see how it can fail unless %FoundFile% contained some special characters which possibly could foul it up. It even looks rather similar to the code in the link that jaclaz posted that was done by Yzöwl. I can not fix something that is not broken. Can only suggest to use delayed expansion with the variables to help avoid character issues.

Link to comment
Share on other sites

The script in the 1st post has been tested here as working in Windows 7 X64. I do not see how it can fail unless %FoundFile% contained some special characters which possibly could foul it up. It even looks rather similar to the code in the link that jaclaz posted that was done by Yzöwl. I can not fix something that is not broken. Can only suggest to use delayed expansion with the variables to help avoid character issues.

Yep :), the point on the other thread being (besides the nice sample by Yzöwl) that using DIR /S on a largish (possibly filled up to the brim) volume will be slow.

If the volume is NTFS formatted, using a search tool parsing just the $MFT will result as waaaay faster.

The suggested tool is MIA (but can be obtained through the Wayback Machine):

http://web.archive.org/web/20130525223305/http://ndff.hotbox.ru/en/

And there is another nice tool here:

http://reboot.pro/topic/18855-windows-file-search-utility-that-is-fast/

 

Just for the record, the bhplt example seemingly only looks for the file in root (which may or may not be what the OP wants)., and nowadays it makes little sense (unless there is a reason for it) to look for files in the A: or B: drive

 

jaclaz

Edited by jaclaz
Link to comment
Share on other sites

Just for the record, the bhplt example seemingly only looks for the file in root (which may or may not be what the OP wants)., and nowadays it makes little sense (unless there is a reason for it) to look for files in the A: or B: drive

@jaclaz, I'm surprised at you. The script, should, and did in my extremely simple test, search the drive recursively. :) Yes, I know that I kept the A and B drive. I did say that I took the OP as a starting point, and changed it just enough to something that I knew had worked for me in the past. The script in the first post, if it did indeed function, worked so slowly on my Win7 x64 system that I also didn't think it was working and canceled it and threw together my script. I'm definitely not saying it should be considered the final product, just a starting point for the OP to complete as he needs it.  Isn't that how you like to help the user learn something for themselves?

Cheers and Regards

Edited by bphlpt
Link to comment
Share on other sites

Here is a VBS script that will search all the local drives for the FILE_NAME

Change FILE_NAME to the name of the file you want to search

 

 Dim Obj Dim Wmi :Set Wmi = GetObject( _  "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Dim Col :Set Col = Wmi.ExecQuery( _  "Select * from CIM_DataFile Where FileName='FILE_NAME'")  If Col.count = 0 Then  WScript.Echo "Missing : FILE_NAME"  WScript.Quit  Else   For Each Obj in Col    Wscript.Echo Obj.Drive & Obj.Path & Obj.FileName & "." & Obj.Extension   Next  End if
Link to comment
Share on other sites

@jaclaz, I'm surprised at you. The script, should, and did in my extremely simple test, search the drive recursively. :)

Good, actually I said "seemingly" as I saw at first sight no /S switch in your DIR command, and did not take the time to actually read the batch, as it seemed to me much more complex than needed.

 

Now that I have read it, please allow me to doubt (though it is possible) that a self calling batch sub will be faster that executing the command with a recursive switch.

 

And now that I have, besides read it, it tested it, getting as result a:

 

****** RICORSIONE BATCH supera i limiti dello STACK******

Conteggio ricorsione=753, utilizzo stack=90 percento

****** ELABORAZIONE BATCH TERMINATA *********

 

error on my XP, I can confirm that your approach is *somehow* not the best one.

 

To replicate, try using it (slightly modified to look only on one disk and to provide some feedback) on a disk (say A:\ ;)) where "test.cmd" is in:

  • root
  • \Afolder\
BUT with the actual batch residing in a directory on C:\ containing a number of directories....

 

 

 

@ECHO OFFSETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONSET /A Counter=0DIR /B /S A:PAUSESET FindFile=mytest.cmdSET FoundFile=NopeCALL :IsItThere "A:" %FindFile% FoundFileIF "!FoundFile!" NEQ "Nope" GOTO :FOUNDECHO ERROR: "%FindFile%" not found.PAUSEEXIT /b:FOUNDECHO File "%FindFile%" found in "%FoundFile%".ENDLOCALPAUSEEXIT /b:IsItThereSET /A Counter+=1SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONSET Result=NopeIF EXIST "%~dp1%2" ((SET "Result=%~dp1")&GOTO :DONE)FOR /F "tokens=*" %%G IN ('dir /B /AD "%~dp1"') DO (IF !Counter!==6 GOTO :DONEECHO !Counter! "%~dp1" CALL :IsItThere "%%G" %2 ResultCALL :IsItThere "%%G" %2 ResultIF "!Result!" NEQ "Nope" GOTO :DONE):DONEENDLOCAL&(SET %3=%Result%)&EXIT /B 0
This is what I get:

C:\batches>findtest2

A:\Afolder

A:\Afolder\mytest.cmd

Premere un tasto per continuare . . .

1 "A:\" CALL :IsItThere "Afolder" mytest.cmd Result

2 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

3 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

4 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "BCDedit_batch" mytest.cmd Result

4 "C:\batches\" CALL :IsItThere "BCDedit_batch" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "CmdasSystem" mytest.cmd Result

3 "C:\batches\" CALL :IsItThere "BCDedit_batch" mytest.cmd Result

4 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "BCDedit_batch" mytest.cmd Result

4 "C:\batches\" CALL :IsItThere "CmdasSystem" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "Atest" mytest.cmd Result

5 "C:\batches\" CALL :IsItThere "CRCMD5" mytest.cmd Result

ERROR: "mytest.cmd" not found.

If I copy mytest.cmd to root of A;\ I get:

C:\batches>findtest2

A:\Afolder

A:\mytest.cmd

A:\Afolder\mytest.cmd

Premere un tasto per continuare . . .

File "mytest.cmd" found in "A:\".

Premere un tasto per continuare . . .

 

jaclaz

Edited by jaclaz
Link to comment
Share on other sites

Although not requested, here's a little script similar to that which I posted in the topic linked earlier.

@ECHO OFF&SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSIONSET/P "TOFIND= Please enter the file search name: "ECHO(&ECHO( Searching Drives for '%TOFIND%'&ECHO(FOR /L %%A IN (90 -1 67) DO (CMD/C EXIT/B %%A    CALL DIR/B/S/A-D "%%=EXITCODEASCII%%:\%TOFIND%" 2>NUL)ECHO(&ECHO(Press any key to exit...&PAUSE>NUL

If you wish to be able to search potential drives A: or B: change 67 to 65

Edited by Yzöwl
forum/browser/os formatting error fixed
Link to comment
Share on other sites

The first batch script only works if the test.cmd file is in the same directory or in the drive root directory.

The VBScript didn't work for me it always says, Missing file.

 

[EDIT]

The linked batch script looks promising i will play a little bit more with it.

@Yzöwl

I couldn't get the last script you posted working, what's the difference between your linked batch script and the one you posted?

Edited by Mike88
Link to comment
Share on other sites

I updated the VBS to include a Inputbox to specify the file name to search all local drives

 

 Dim Col, Obj, Str, Wmi :Str = InputBox("Type The Name Of the File To Find")   If Str <> "" Then    Set Wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")  Set Col = Wmi.ExecQuery("Select * from CIM_DataFile Where FileName='" & Str & "'")   If Col.count = 0 Then      WScript.Echo "Missing : " & Str       WScript.Quit   Else     For Each Obj in Col     Wscript.Echo Obj.Drive & Obj.Path & Obj.FileName & "." & Obj.Extension    Next    End If      Else    WScript.Echo "User Cancel"     End If

The VBScript didn't work for me it always says, Missing file.

Perhaps you missed this

Change FILE_NAME to the name of the file you want to search

You have to change this line in the VBS script and FILE_NAME changed to name you are searching for

"Select * from CIM_DataFile Where FileName='FILE_NAME'")

Just a note that this VBS script does check map drives on the network

Test the script using the word test and the results it returned, Z being my map drive

c:\users\gunsmokingman\appdata\local\temp\test.wav

c:\users\gunsmokingman\desktop\hta media player\test.txt

e:\gunsmokingman\appdata\local\temp\test.wav

e:\music\test.vbs

e:\zzz_win7\z1_me\gunsmokingman\desktop\hta\test.hta

e:\zzz_win7\z1_me\gunsmokingman\desktop\mycmd\test.txt

k:\gunsmokingman\desktop\cmd\Test.txt

k:\gunsmokingman\desktop\hta\Test.hta

k:\gunsmokingman\documents\nhl09\Test.dyn

k:\gunsmokingman\resourcehacker\shell32win7icons\Test.rc

z:\vistahomebeta\test.txt

Link to comment
Share on other sites

@gunsmokingman

I also tried you input VBScript but it also couldn't find the test.cmd file.

A Batch script is also a more easy way for me to integrate into my existing Batch script. ;)

 

@Wise Owl

This now works nicely do you also know how to do it so it would execute the test.cmd file if found?

Edited by Mike88
Link to comment
Share on other sites

The second script found every instance of test on my local drives and my map drive the input only require the name and no extension.

This Test.txt return missing file, where as test return this

c:\users\gunsmokingman\appdata\local\temp\test.wav

c:\users\gunsmokingman\desktop\hta media player\test.txt

e:\gunsmokingman\appdata\local\temp\test.wav

e:\music\test.vbs

e:\zzz_win7\z1_me\gunsmokingman\desktop\hta\test.hta

e:\zzz_win7\z1_me\gunsmokingman\desktop\mycmd\test.txt

k:\gunsmokingman\desktop\cmd\Test.txt

k:\gunsmokingman\desktop\hta\Test.hta

k:\gunsmokingman\documents\nhl09\Test.dyn

k:\gunsmokingman\resourcehacker\shell32win7icons\Test.rc

z:\vistahomebeta\test.txt

Being it a WMI based script you could change the query to include the extension, or hard code it to a specific file type.

Example

"Select * from CIM_DataFile Where Extension = 'FILE_EXTENSION' And FileName='FILE_NAME'")

Link to comment
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...