Получить путь к исполняемому файлу из команды (как cmd)

учитывая путь стиля командной строки к команде, такой как bin/server.exe или ping, Как я могу получить полный путь к этому исполняемому файлу (как cmd или Process.Start разрешит ли это)?

пробовал Path.GetFullPath, но он постоянно расширяется относительно рабочего каталога. Он расширяется bin/server.exe правильно, однако учитывая ping возвращает c:usersmattping (несуществующих). Я хочу!--8-->.

Edit: я хотел бы такое же поведение, как cmd. Некоторые соображения:

  1. когда существует локальный исполняемый файл с тем же именем, что и в пути, cmd предпочитает локальный
  2. cmd может развернуть команду server to server.bat или server.exe (добавить расширение файла)

Я также попробовал инструмент командной строки Windows под названием where . Это почти хочу:

отображает расположение файлов, соответствующих шаблону поиска. По умолчанию поиск выполняется по текущему каталогу и в путях, указанных переменной среды PATH.

>where ping
C:WindowsSystem32PING.EXE
>where binserver
INFO: Could not find files for the given pattern(s).

(этот вопрос трудно найти вокруг из-за двух разных значений слова "путь")

5 ответов


учитывая 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 без ведущей точки.


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

Если вас интересует только поиск текущего каталога и путей, указанных в переменной среды 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;
}

вы должны искать весь диск.

Windows может реагировать на такие вещи, как iexplore, ping, cmd и т. д., Потому что они находятся в реестре под этим ключом:

HKEY_LOCAL_MACHINE
   SOFTWARE
       Microsoft
           Windows
               CurrentVersion
                   App Paths

единственный другой способ-поиск приложения по всему диску.

EDIT: насколько я понимаю, вы хотите искать любое случайное исполняемое имя, а не те, которые уже известны Windows..


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

HTH