The order in which paths are searched is actually registry-dependent, so simply enumerating through the PATH environment variable is not guaranteed to produce the expected result, particularly where there is a file of the expected name in the current working directory. To reliably get the executable path, you will want to call the SearchPath
Win32 function in Kernel32.
There is no framework .NET function that exposes SearchPath
, but the function can be invoked directly through P/Invoke.
The following sample program illustrates the usage of this function. If notepad.exe exists in the system search paths, per the system configuration, it will print the path; if it does not exist, it will print "File not found" instead.
using System;
using System.Text;
using System.Runtime.InteropServices;
class Program
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint SearchPath(string lpPath,
string lpFileName,
string lpExtension,
int nBufferLength,
[MarshalAs ( UnmanagedType.LPTStr )]
StringBuilder lpBuffer,
out IntPtr lpFilePart);
const int MAX_PATH = 260;
public static void Main()
{
StringBuilder sb = new StringBuilder(MAX_PATH);
IntPtr discard;
var nn = SearchPath(null, "notepad.exe", null, sb.Capacity, sb, out discard);
if (nn == 0)
{
var error = Marshal.GetLastWin32Error();
// ERROR_FILE_NOT_FOUND = 2
if (error == 2) Console.WriteLine("No file found.");
else
throw new System.ComponentModel.Win32Exception(error);
}
else
Console.WriteLine(sb.ToString());
}
}