0

No matter if I run the application as Administrator or not, I always get an System.UnauthorizedAccessException exception when trying to search for specific files within the "Program files" folder.

The code looks like this, and the exception occurs at System.IO.Directory.GetFiles(..)

        //--- Find folders Application path
        {
        try
            {
                string searchfile = "terminal64.exe";
                string searchdir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
                string[] files = System.IO.Directory.GetFiles(searchdir, searchfile, System.IO.SearchOption.AllDirectories);

                for (int i = 0; i < files.Length; i++)
                {
                    string result = files[i];
                    int p=result.IndexOf(searchfile);
                    if (p>0)
                    {
                        result = result.Substring(0, p);
                        AddTargetFolder(result);
                    }
                }
                    
            }
        catch
            {

            }
        }

I am using Visual Studio 2019. The exception is thrown in the debugger (VS is executed as Administrator) as well as when executing the final .exe file.

Any help is much appreciated.

Doerk
  • 71
  • 8
  • Which line throws the exception? is it the GetFolderPath, or the GetFiles, or somewhere else? – Neil Apr 08 '21 at 11:46
  • 1
    The Program Files folder itself and many subfolders are system protected. GetFiles has no way to avoid an exception when it tries to read info about a secured entry in that folder. – Steve Apr 08 '21 at 11:48
  • As described its the GetFiles() function which throws the exception. Actually I just need the first level, no further subfolders. Is there another way round besides GetFiles()? – Doerk Apr 08 '21 at 12:43

2 Answers2

0

I would move GetFiles into a try-catch block and if it is an UnauthorizedAccessException I would ignore it and continue.

  • Doesn't work. The array files is empty then. – Doerk Apr 08 '21 at 12:41
  • 1
    @Doerk maybe this will help you: https://stackoverflow.com/questions/1393178/unauthorizedaccessexception-cannot-resolve-directory-getfiles-failure Maybe do this as an list and after search replace all empty items? – Nacho Imperium Apr 08 '21 at 13:13
0

Here comes the final solution. Please, be so kind and rate this question as helpful, if you find it useful in general. Thanks to all who helped.

using System;
using System.IO;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public static class FileDirectorySearch
    {
        public static IEnumerable<string> Search(string searchPath, string searchPattern)
        {
            IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern);

            foreach (string file in files)
            {
                yield return file;
            }

            IEnumerable<string> directories = GetDirectories(searchPath);

            foreach (string directory in directories)
            {
                files = Search(directory, searchPattern);

                foreach (string file in files)
                {
                    yield return file;
                }
            }
        }

        private static IEnumerable<string> GetDirectories(string directory)
        {
            IEnumerable<string> subDirectories = null;
            try
            {
                subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly);
            }
            catch (UnauthorizedAccessException)
            {
            }

            if (subDirectories != null)
            {
                foreach (string subDirectory in subDirectories)
                {
                    yield return subDirectory;
                }
            }
        }

        private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern)
        {
            IEnumerable<string> files = null;
            try
            {
                files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
            }
            catch (UnauthorizedAccessException)
            {
            }

            if (files != null)
            {
                foreach (string file in files)
                {
                    yield return file;
                }
            }
        }
    }

    class Program
    {



        static void Main(string[] args)
        {
            //--- Find folders Application path
            {
                try
                {
                    string searchfile = "terminal64.exe";
                    string searchdir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

                    IEnumerable<string> filesOrDirectories = FileDirectorySearch.Search(searchdir, searchfile);

                    foreach (string fileOrDirectory in filesOrDirectories)
                    {
                        // Do something here.
                        Console.WriteLine(fileOrDirectory);
                    }
                }
                catch
                {
                    Console.WriteLine("Catch");
                }
                Console.ReadKey();
            }
        }
    }
}
Doerk
  • 71
  • 8