19

过去,我在许多 C 和 C++ 应用程序中使用了扩展通配符参数的 setargv.obj 链接,但对于 .net 应用程序,我找不到任何类似的提及。

是否有一种标准方法可以让您的应用程序的命令行参数自动扩展通配符?(即,将 *.doc 从 args 参数中的一个条目扩展到与该通配符匹配的所有条目)。

PS我已经为我当前的小项目与 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

4 回答 4

9

这是我粗略的技巧。我希望它是递归的。经历过 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();
}
于 2010-05-12T13:23:19.180 回答
4

我不确定你到底在追求什么......但如果我用你提到的 Directory.GetFiles() “hack”得到你要去的地方,那么这样的事情可能会起作用:

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)

这将抓取与 Windows 目录中的 sys* 通配符匹配的所有目录及其下的所有目录。

如果您想变得比这更复杂,那么我不确定您将如何做到这一点...例如,假设您想要直接包含在 Windows 目录中的文件夹中的文件夹-我不知道您会如何恐怕要去做类似的事情......我不认为将整个树结构导出到 XML 并使用 XPath 来做到这一点会如此高效 - 使用通配符解析 XPath 将非常简单 - 但转换为XML不会那么有效......

于 2008-12-19T16:37:14.443 回答
3

查看 Microsoft.Build.dll 中反汇编的 Microsoft.Build.Shared.FileMatcher 类的源代码,您可以从方法 GetFiles 的实现中得到一些想法。

作为客户,您可以使用以下方法

var filelist = FileMatcher.GetFiles(@"c:\alaki",@"c:\alaki\**\bin\*.dll");
于 2012-07-16T04:39:43.507 回答
1

你的代码看起来就像你应该做的那样。

于 2008-12-23T00:51:24.053 回答