6

I have an executable name, like "cmd.exe" and need to resolve it's fully-qualified path. I know the exe appears in one of the directories listed in the PATH environment variable. Is there a way to resolve the full path without parsing and testing each directory in the PATH variable? basically I don't want to do this:

foreach (string entry in Environment.GetEnvironmentVariable("PATH").Split(';'))
    ...

There has to be a better way, right?

csharptest.net
  • 58,500
  • 11
  • 67
  • 87

4 Answers4

10

Here's another approach:

string exe = "cmd.exe";
string result = Environment.GetEnvironmentVariable("PATH")
    .Split(';')
    .Where(s => File.Exists(Path.Combine(s, exe)))
    .FirstOrDefault();

Result: C:\WINDOWS\system32

The Path.Combine() call is used to handle paths that don't end with a trailing slash. This will properly concatenate the strings to be used by the File.Exists() method.

Ahmad Mageed
  • 91,579
  • 18
  • 159
  • 169
5

You could Linq it with

string path = Environment
                .GetEnvironmentVariable("PATH")
                .Split(';')
                .FirstOrDefault(p => File.Exists(p + filename));

A little more readable maybe?

Dan

Daniel Elliott
  • 22,229
  • 10
  • 62
  • 82
  • 1
    I believe you need to correctly construct the path before you can call File.Exists. File.Exists(Path.Combine(p, filename)) – Lee Jensen Dec 17 '15 at 16:29
2

Well, I did find the following; however, I think I'll stick to the managed implementation.

    static class Win32
    {
        [DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = false)]
        static extern bool PathFindOnPath([MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszFile, IntPtr unused);

        public static bool FindInPath(String pszFile, out String fullPath)
        {
            const int MAX_PATH = 260;
            StringBuilder sb = new StringBuilder(pszFile, MAX_PATH);
            bool found = PathFindOnPath(sb, IntPtr.Zero);
            fullPath = found ? sb.ToString() : null;
            return found;
        }
    }
csharptest.net
  • 58,500
  • 11
  • 67
  • 87
1

This seems like a pretty good way of doing it already -- as far as I know, searching through the directories in the PATH environment variable is what Windows does anyway when it's trying to resolve a path.

Donut
  • 103,927
  • 20
  • 129
  • 143