使用通配符遍历目录 - 内置方法?

时间:2013-11-18 15:22:34

标签: c# filesystems wildcard

我正在尝试查找可以位于多个位置之一的文件xsd.exe,并选择具有最新时间戳的文件。这个文件有很多不同的版本;仅在我的开发系统上,我就有8个不同的版本,大多数情况下,如果不是所有版本看起来彼此不同。

我想要做的是设置一个初始化程序,查看公共位置,收集可能候选人的列表,然后从中选择。

我认为我有一个非常优雅的方法:

var potentialLocations = new[]
    {
        @"C:\Program Files (x86)\Microsoft SDKs\Windows\*\Bin\*",
        @"C:\Program Files\Microsoft SDKs\Windows\*\bin",
        @"C:\Program Files\Microsoft Visual Studio*\SDK\*\Bin"
    };

IEnumerable<FileInfo> files = new List<FileInfo>();
files = potentialLocations.Aggregate(files,
                                        (current,
                                        potentialLocation) =>
                                        current.Concat(
                                            Directory.GetDirectories(potentialLocation)
                                                    .Select(x => new DirectoryInfo(x))
                                                    .SelectMany(x => x.GetFiles("xsd.exe"))));

var file = files
    .OrderByDescending(x => x.CreationTimeUtc)
    .FirstOrDefault();

...但不幸的是,Directory.GetDirectories不喜欢我的通配符模式;我得到一个ArgumentException:“路径中的非法字符”。

是否有方法使用我指定的通配符遍历这些目录结构?或者我是否必须为此制作一些定制的东西?

1 个答案:

答案 0 :(得分:1)

没有内置方法可以为您执行此操作,但您可以构建它。

GetDirectories方法有一个你可以使用的搜索模式overload,但它只会让你成为那里的一部分。例如,下面的代码将为您提供Program Files (x86)文件夹下的所有bin文件夹。

var directories = System.IO.Directory.GetDirectories("C:\\Program Files (x86)", @"Bin", System.IO.SearchOption.AllDirectories);

foreach (var dir in directories)
    Console.WriteLine(dir);

或者,如果您只想要Program Files (x86)中的所有Microsoft文件夹,则可以执行此操作:

var directories = System.IO.Directory.GetDirectories("C:\\Program Files (x86)", @"Microsoft*", System.IO.SearchOption.TopDirectoryOnly);

foreach (var dir in directories)
    Console.WriteLine(dir);

我说它只会让你成为那里的一部分,因为GetDirectories覆盖不会让你使用包含子目录的字符串,如Microsoft Visual Studio*\SDK\

如果您想要使用多个通配符和子目录进行更精细的控制,那么您需要手动解析字符串,然后利用覆盖来搜索匹配。