Есть ли вариант расширения с подстановочными знаками для приложений .net? - PullRequest
17 голосов
/ 19 декабря 2008

В прошлом я использовал ссылку setargv.obj для Расширения групповых аргументов для ряда приложений на C и C ++, но я не могу найти никакого подобного упоминания для приложений .net.

Существует ли стандартный способ автоматического расширения подстановочных знаков параметров командной строки вашего приложения? (т. Е. Расширение * .doc из одной записи в параметре args до всех, соответствующих этому подстановочному знаку) .

P.S. Я взломал что-то вместе с Directory.GetFiles () для моего текущего небольшого проекта, но он не покрывает подстановочные знаки путями (пока), и было бы неплохо сделать это без специального кода.

Обновление: вот мой грубый взлом, для иллюстрации. Необходимо разделить параметры для пути и имени для GetFiles, но это общая идея. При связывании setargv.obj с приложением на C или C ++ все расширения с подстановочными знаками выполняются в основном, и пользователю остается только выполнять итерации по массиву argv.


static void Main(string[] args)
{
    foreach (String argString in args)
    {
        // Split into path and wildcard
        int lastBackslashPos = argString.LastIndexOf('\\') + 1;
        path = argString.Substring(0, lastBackslashPos);
        filenameOnly = argString.Substring(lastBackslashPos, 
                                   argString.Length - lastBackslashPos);

        String[] fileList = System.IO.Directory.GetFiles(path, filenameOnly);
        foreach (String fileName in fileList)
        {
            //do things for each file
        }
    }
}

Ответы [ 4 ]

9 голосов
/ 12 мая 2010

Вот нам мой грубый хак. Я хотел бы, чтобы это было рекурсивным. И испытав недостаток подстановочных знаков Windows, я мог бы решить использовать регулярные выражения вместо того, чтобы позволить GetFiles () сделать это для меня.

using System.IO;

public static string[] ExpandFilePaths(string[] args)
{
    var fileList = new List<string>();

    foreach (var arg in args)
    {
        var substitutedArg = System.Environment.ExpandEnvironmentVariables(arg);

        var dirPart = Path.GetDirectoryName(substitutedArg);
        if (dirPart.Length == 0)
            dirPart = ".";

        var filePart = Path.GetFileName(substitutedArg);

        foreach (var filepath in Directory.GetFiles(dirPart, filePart))
            fileList.Add(filepath);
    }

    return fileList.ToArray();
}
4 голосов
/ 19 декабря 2008

Я не уверен, что именно вы ищете ... но если я получу, куда вы идете, с "взломом" Directory.GetFiles (), который вы упомянули, то что-то вроде этого может работать:

var Dirs = Directory.GetDirectories(@"C:\Windows", "sys*", 
SearchOption.TopDirectoryOnly).ToList();
var Files = new List<String>();
Dirs.ForEach(dirName => Files.AddRange(Directory.GetFiles(dirName, "*.sys", SearchOption.AllDirectories)));

Параметр подстановки при вызове GetDirectories позволит вам получить все каталоги, содержащиеся в папке Windows [непосредственно], которые соответствуют шаблону "sys *".

Затем вы можете перебирать те папки, собирая все файлы, которые соответствуют шаблону "* .sys".

Это то, что вы ищете? Чтобы автоматически развернуть аргументы, вам нужно будет извлечь какие-то осмысленные символы и применить их к этой модели ...

Например:

RunMyApp "C: \ Windows \ Sys * \ * .sys"

Вы бы вытащили строку C: \ Windows - возможно, с помощью регулярного выражения, нашли бы каталог самого низкого уровня, не содержащий подстановочный знак, и применили бы его к методу GetDirectories, добавив строку с подстановочными символами в качестве параметра поиска.

Тогда если ваш конец строки (в данном случае * .sys) в качестве шаблона поиска для Directory.GetFiles.

Если вы хотите все усложнить и сделать что-то вроде:

C:\Windows\*\Sys*\*.sys

Вы должны использовать SearchOptions, чтобы установить это поведение:

Directory.GetDirectories(@"C:\Windows", "sys*", SearchOptions.AllDirectories)

При этом будут извлечены все каталоги, которые соответствуют шаблону sys * в каталоге Windows, и все каталоги под ним.

Если вы хотите сделать все намного сложнее, то я не уверен, как бы вы это сделали ... например, скажем, вы хотели, чтобы папки, содержащиеся в папках непосредственно внутри каталога Windows, - я понятия не имею, как бы вы поступили примерно так, я боюсь ... я не представляю, что экспорт всей древовидной структуры в XML и использование XPath для этого было бы настолько эффективно - XPath было бы невероятно просто для анализа с использованием подстановочных знаков - но преобразование в XML не было бы таким эффективным ...

3 голосов
/ 16 июля 2012

см. Исходный код разобранного класса Microsoft.Build.Shared.FileMatcher в Microsoft.Build.dll Вы можете получить представление о реализации метода GetFiles.

в качестве клиента вы можете использовать метод следующим образом

var filelist = FileMatcher.GetFiles(@"c:\alaki",@"c:\alaki\**\bin\*.dll");
2 голосов
/ 23 декабря 2008

Ваш код выглядит именно так, как вы должны это делать.

...