Search for specific file name in directory

六眼飞鱼酱① 提交于 2020-01-02 10:24:15

问题


I'm trying to search for specific file name on all volumes on the system, except System Volume Information or Windows Directories and print out every full path for each file.

I've tried to use Directory.GetFiles, but it only searche inside Drive C:\ or Drive D:\ (depends which drive is specified)

How can I achieve my goal?

For example I want to run program and search for file with name ".DS_Store" (used to use mac, and now my file system is full of these files....)

I would really appreciate any help. Thank you in advance

UPD. Program Should be executed with Admin rights to work


回答1:


As part of a cryptolocker analysis, I wrote a prototype that locates target extensions, here is how to use it

var cmd = new LocateTargetFilesCommand();
cmd.Execute()

It will search all the drives for two extensions: .xlsx and .doc. The biggest problem is to handle permissions issue. Also a child folder may have wider permissions, so if you cannot access a parent folder, you can still potentially access its roots.

At the end, cmd.FoundTargets will contain absolute paths to the found files with desired extensions

public class LocateTargetFilesCommand 
{
    private string[] _targetExtensions = new[]
        {
            "xlsx", "doc"
        };

    public LocateTargetFilesCommand()
    {
        FoundTargets = new ConcurrentQueue<string>();
        DirsToSearch = new List<string>();
    }

    public ConcurrentQueue<string> FoundTargets { get; private set; }
    public List<string> DirsToSearch { get; private set; }

    public void Execute()
    {
        DriveInfo[] driveInfos = DriveInfo.GetDrives();

        Console.WriteLine("Start searching");
        foreach (var driveInfo in driveInfos)
        {

            if (!driveInfo.IsReady)
                continue;

            Console.WriteLine("Locating directories for drive: " + driveInfo.RootDirectory);
            GetAllDirs(driveInfo.RootDirectory.ToString());
            Console.WriteLine("Found {0} folders", DirsToSearch.Count);

            foreach (var ext in _targetExtensions)
            {
                Console.WriteLine("Searching for .*" + ext);

                int currentNotificationProgress = 0;
                for (int i = 0; i < DirsToSearch.Count; i++)
                {
                    int progressPercentage = (i * 100) / DirsToSearch.Count;
                    if (progressPercentage != 0)
                    {
                        if (progressPercentage % 10 == 0 && currentNotificationProgress != progressPercentage)
                        {
                            Console.WriteLine("Completed {0}%", progressPercentage);
                            currentNotificationProgress = progressPercentage;
                        }
                    }

                    var dir = DirsToSearch[i];
                    try
                    {
                        string[] files = Directory.GetFiles(dir, "*." + ext, SearchOption.TopDirectoryOnly);
                        foreach (var file in files)
                        {
                            FoundTargets.Enqueue(file);
                        }
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        Console.WriteLine("Skipping directory: {0}", dir);
                        DirsToSearch.Remove(dir);
                    }
                }

                Console.WriteLine("So far located {0} targets", FoundTargets.Count);
            }

            DirsToSearch.Clear();
        }

        Console.WriteLine("Stop searching");
    }

    public void GetAllDirs(string root)
    {
        try
        {
            string[] dirs = Directory.GetDirectories(root);
            DirsToSearch.AddRange(dirs);
            foreach (var dir in dirs)
            {
                GetAllDirs(dir);
            }
        }
        catch (UnauthorizedAccessException)
        {
            //swallow
        }
    }
}



回答2:


Use GetLogicalDrives

foreach (var d in Directory.GetLogicalDrives())
{         
     var files = Directory.GetFiles(d, file);         
}



回答3:


Try this:

foreach (var drive in Directory.GetLogicalDrives())
{
    foreach (var fileInfo in from dir in Directory.GetDirectories(drive) from file in Directory.GetFiles(dir) select new FileInfo(file))
    {
        // get all details in fileInfo
    }
}



回答4:


Thanks to oleksii, but here is how I used this code to exclude all System directories:

public class LocateTargetFilesCommand
{
    private string[] _targetExtensions = new[]
    {
        ".DS_Store"
    };

    public LocateTargetFilesCommand()
    {
        FoundTargets = new ConcurrentQueue<string>();
        DirsToSearch = new List<string>();
    }

    public ConcurrentQueue<string> FoundTargets { get; private set; }
    public List<string> DirsToSearch { get; private set; }

    public void Execute()
    {
        DriveInfo[] driveInfos = DriveInfo.GetDrives();

        Console.WriteLine("Start searching");
        foreach (var driveInfo in driveInfos)
        {
            if (!driveInfo.IsReady)
                continue;

            Console.WriteLine("Locating directories for drive: " + driveInfo.RootDirectory);
            GetAllDirs(driveInfo.RootDirectory.ToString());
            Console.WriteLine("Found {0} folders", DirsToSearch.Count);

            foreach (var ext in _targetExtensions)
            {
                Console.WriteLine("Searching for " + ext);

                int currentNotificationProgress = 0;
                for (int i = 0; i < DirsToSearch.Count; i++)
                {
                    int progressPercentage = (i * 100) / DirsToSearch.Count;
                    if (progressPercentage != 0)
                    {
                        if (progressPercentage % 10 == 0 && currentNotificationProgress != progressPercentage)
                        {
                            Console.WriteLine("Completed {0}%", progressPercentage);
                            currentNotificationProgress = progressPercentage;
                        }
                    }

                    var dir = DirsToSearch[i];
                    try
                    {
                        string[] files = Directory.GetFiles(dir, ext, SearchOption.TopDirectoryOnly);
                        foreach (var file in files)
                        {
                            FoundTargets.Enqueue(file);
                        }
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        Console.WriteLine("Skipping directory: {0}", dir);
                        DirsToSearch.Remove(dir);
                    }
                }

                Console.WriteLine("So far located {0} targets", FoundTargets.Count);
            }

            DirsToSearch.Clear();
        }

        Console.WriteLine("Stop searching");
    }

    public void GetAllDirs(string root)
    {
        try
        {
            string[] dirs = Directory.GetDirectories(root);
            DirsToSearch.AddRange(dirs);
            foreach (var dir in dirs)
            {   
                if(dir.Contains("Windows"))
                    Console.WriteLine("Skipped Windows Directory");
                else if (dir.Contains("Users"))
                    Console.WriteLine("Skipped Users Directory");
                else if (dir.Contains("MSOCache"))
                    Console.WriteLine("Skipped MSOCache Directory");
                else if (dir.Contains("SYSTEM.SAV"))
                    Console.WriteLine("Skipped SYSTEM.SAV Directory");
                else if (dir.Contains("ProgramData"))
                    Console.WriteLine("Skipped ProgramData Directory");
                else if (dir.Contains("System Volume Information"))
                    Console.WriteLine("Skipped System Volume Information Directory");
                else if (dir.Contains("$SysReset"))
                    Console.WriteLine("Skipped $SysReset Directory");
                else
                    GetAllDirs(dir);
            }
        }
        catch (UnauthorizedAccessException)
        {

        }
    }
}


来源:https://stackoverflow.com/questions/22938445/search-for-specific-file-name-in-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!