.net 如何使用环境路径找到可能不完全限定的文件?

pxyaymoc  于 9个月前  发布在  .NET
关注(0)|答案(6)|浏览(76)

我有一个可执行文件的名称,如“xml.exe”,需要解决它的完全限定路径。我知道exe出现在PATH环境变量中列出的一个目录中。有没有一种方法可以解析完整的路径,而不需要解析和测试PATH变量中的每个目录?基本上我不想这么做

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

一定有更好的办法,对吧?

eivnm1vs

eivnm1vs1#

这里是另一种方法:

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

结果:C:\WINDOWS\system32
Path.合并()调用用于处理不以斜杠结尾的路径。这将正确地连接File. js()方法使用的字符串。

qcuzuvrc

qcuzuvrc2#

你可以把它和

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

更容易读一点?

soat7uwm

soat7uwm3#

这似乎是一种很好的方法--据我所知,在PATH环境变量中搜索目录是Windows在试图解析路径时所做的事情。

kqlmhetl

kqlmhetl4#

我发现了以下几点但是,我想我还是坚持使用托管实现。

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;
        }
    }
slsn1g29

slsn1g295#

最后我写了这个函数:

private static string GetExecutablePath(string executableFileName)
{
    var path = Environment
        .GetEnvironmentVariable("PATH")!
        .Split(';')
        .Select(s => Path.Combine(s, executableFileName))
        .FirstOrDefault(x => File.Exists(x));
    if (path == null)
    {
        throw new Exception($"Cannot find {executableFileName}. Is it installed on your computer?");
    }
    return path;
}

在我的例子中,我想找到python.exe的路径,所以我这样调用函数:

GetExecutablePath("python.exe")

在我的例子中返回:

"C:\\Program Files\\Python39\\python.exe"
k3fezbri

k3fezbri6#

在现有答案的基础上添加几个注解,特别是关于制定一个更加平台无关的方法:

  • 分割为System.IO.Path.PathSeparator。这在Windows上解析为';',在其他任何东西上解析为':'
  • 另外,建议传递StringSplitOptions.RemoveEmptyEntries,以避免潜在的边缘情况。
  • 检查带有和不带有扩展名.exe的可执行文件。
  • 不幸的是,如果您必须处理跨平台支持,事情总是变得混乱(可读性较差)。抱歉

相关问题