11

给定命令的命令行样式路径,例如bin/server.exeor ping,我如何获得该可执行文件的完整路径(作为 cmd 或Process.Start将解析它)?

我试过Path.GetFullPath了,但它总是相对于工作目录扩展。它可以正确扩展bin/server.exe,但是如果ping它返回c:\users\matt\ping(不存在)。我想要c:\Windows\system32\ping.exe

编辑:我想要与 cmd 相同的行为。一些考虑:

  1. 当路径中有同名的本地可执行文件时, cmd 首选本地可执行文件
  2. cmd 可以将命令扩展serverserver.batserver.exe添加文件扩展名

我还尝试了 Windows 的命令行工具where. 它几乎是我想要的:

显示与搜索模式匹配的文件的位置。默认情况下,搜索是沿着当前目录和 PATH 环境变量指定的路径进行的。

>where ping
C:\Windows\System32\PING.EXE
>where bin\server
INFO: Could not find files for the given pattern(s).

(这个问题很难搜索,因为“路径”这个词有两种不同的含义)

4

5 回答 5

14

也考虑到 PATHEXT,从 Serj-Tm 的答案中窃取(对不起!+1 给他):

public static string WhereSearch(string filename)
{
    var paths = new[]{ Environment.CurrentDirectory }
            .Concat(Environment.GetEnvironmentVariable("PATH").Split(';'));
    var extensions = new[]{ String.Empty }
            .Concat(Environment.GetEnvironmentVariable("PATHEXT").Split(';')
                       .Where(e => e.StartsWith(".")));
    var combinations = paths.SelectMany(x => extensions,
            (path, extension) => Path.Combine(path, filename + extension));
    return combinations.FirstOrDefault(File.Exists);
}

抱歉,缩进有点乱 - 我试图让它不滚动。我不知道 StartsWith 检查是否真的有必要 - 我不确定 CMD 如何处理没有前导点的 pathext 条目。

于 2012-07-26T15:20:22.760 回答
9
public static string GetFullPath(string filename)    
{
 return new[]{Environment.CurrentDirectory}
  .Concat(Environment.GetEnvironmentVariable("PATH").Split(';'))
  .Select(dir => Path.Combine(dir, filename))
  .FirstOrDefault(path => File.Exists(path));
}
于 2012-07-26T11:38:14.547 回答
4

如果您只对搜索当前目录和 PATH 环境变量中指定的路径感兴趣,则可以使用以下代码段:

public static string GetFullPath(string fileName)
{
    if (File.Exists(fileName))
        return Path.GetFullPath(fileName);

    var values = Environment.GetEnvironmentVariable("PATH");
    foreach (var path in values.Split(';'))
    {
        var fullPath = Path.Combine(path, fileName);
        if (File.Exists(fullPath))
            return fullPath;
    }

    return null;
}
于 2012-07-26T11:23:08.283 回答
3

您必须搜索整个磁盘。

Windows 可以响应 iexplore、ping、cmd 等内容,因为它们位于注册表项下:

HKEY_LOCAL_MACHINE
   SOFTWARE
       Microsoft
           Windows
               CurrentVersion
                   App Paths

唯一的另一种方法是在整个磁盘中搜索应用程序。

编辑:我的理解是,您要搜索任何随机的可执行文件名称,而不是 Windows 已经知道的名称。

于 2012-07-26T11:21:54.617 回答
2
internal class Program
{
    static void Main(string[] args)
    {
        string fullPath = GetExactPathFromEnvironmentVar("ping.exe");
        if (!string.IsNullOrWhiteSpace(fullPath))
            Console.WriteLine(fullPath);
        else
            Console.WriteLine("Not found");
    }

    static string GetExactPathFromEnvironmentVar(string program)
    {
        var pathVar = System.Environment.GetEnvironmentVariable("PATH");
        string[] folders = pathVar.Split(';');

        foreach (var folder in folders)
        {
            string path = Path.Combine(folder, program);
            if (File.Exists(path))
            {
                return path;
            }
        }

        return null;
    }
}

高温高压

于 2012-07-26T11:21:50.523 回答