我正在使用TFS 2010 Team Build自定义构建流程模板的默认工作流程。有一个名为FindMatchingFiles
的活动允许搜索具有MatchPattern
属性中定义的模式的特定文件。如果我只指定一个文件扩展名,它可以工作。例如:
String.Format("{0}\\**\\\*.msi", SourcesDirectory)
但我想包括* .exe。尝试以下模式,但它不起作用:
String.Format("{0}\\**\\\*.(msi|exe)", SourcesDirectory)
任何人都可以告诉我如何纠正它?
答案 0 :(得分:14)
您可以使用String.Format("{0}\**\*.msi;{0}\**\*.exe", SourcesDirectory)
答案 1 :(得分:4)
FindMatchingFiles
activity的MatchPattern
属性使用
Directory.GetFiles(String, String)
方法的searchPattern
参数支持的语法。
这意味着您无法组合多个扩展程序。您需要两次调用FindMatchingFiles
活动。然后,您可以在使用它们时合并这两个调用的结果(即,如果结果为msiFiles
和exeFiles
,则可以使用msiFiles.Concat(exeFiles)
作为ForEach
的输入)。
但是,正如您在@antwoord's answer中看到的那样,该活动实际上似乎接受了以分号分隔的模式列表,与Directory.GetFiles
不同。
答案 2 :(得分:0)
FindMatchingFiles有一些奇怪的搜索模式。这是代码(使用ILSpy反编译),因此您可以测试搜索模式,而无需启动新版本。
它在以下位置包含一个硬编码的根目录(Z:)
List<string> matchingDirectories = GetMatchingDirectories(@"Z:", matchPattern.Substring(0, num), 0);
代码:
using System;
using System.Collections.Generic;
using System.IO;
namespace DirectoryGetFiles
{
//// Use the FindMatchingFiles activity to find files. Specify the search criteria in the MatchPattern (String) property.
//// In this property, you can specify an argument that includes the following elements:
//// Syntax that is supported by the searchPattern argument of the Directory GetFiles(String, String) method.
////
//// ** to specify a recursive search. For example:
//// To search the sources directory for text files, you could specify something that resembles the following
//// value for the MatchPattern property: String.Format("{0}\**\*.txt", SourcesDirectory).
////
//// To search the sources directory for text files in one or more subdirectories that are called txtfiles,
//// you could specify something that resembles the following value for the MatchPattern property:
//// String.Format("{0}\**\txtfiles\*.txt", SourcesDirectory).
class Program
{
static void Main(string[] args)
{
string searchPattern = @"_PublishedWebsites\Web\Scripts\jasmine-specs**\*.js";
var results = Execute(searchPattern);
foreach (var i in results)
{
Console.WriteLine("found: {0}", i);
}
Console.WriteLine("Done...");
Console.ReadLine();
}
private static IEnumerable<string> Execute(string pattern)
{
string text = pattern;
text = text.Replace(";;", "\0");
var hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
string[] array = text.Split(new char[]
{
';'
}, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i];
string text3 = text2.Replace("\0", ";");
if (IsValidPattern(text3))
{
List<string> list = ComputeMatchingPaths(text3);
if (list.Count > 0)
{
using (List<string>.Enumerator enumerator = list.GetEnumerator())
{
while (enumerator.MoveNext())
{
string current = enumerator.Current;
hashSet.Add(current);
}
goto IL_15C;
}
}
////Message = ActivitiesResources.Format("NoMatchesForSearchPattern", new object[]
}
else
{
//// Message = ActivitiesResources.Format("InvalidSearchPattern", new object[]
}
IL_15C: ;
}
return hashSet;//.OrderBy((string x) => x, FileSpec.TopDownComparer);
}
private static bool IsValidPattern(string pattern)
{
string text = "**" + Path.DirectorySeparatorChar;
int num = pattern.IndexOf(text, StringComparison.Ordinal);
return (num < 0 || (pattern.IndexOf(text, num + text.Length, StringComparison.OrdinalIgnoreCase) <= 0 && pattern.IndexOf(Path.DirectorySeparatorChar, num + text.Length) <= 0)) && pattern[pattern.Length - 1] != Path.DirectorySeparatorChar;
}
private static List<string> ComputeMatchingPaths(string matchPattern)
{
List<string> list = new List<string>();
string text = "**" + Path.DirectorySeparatorChar;
int num = matchPattern.IndexOf(text, 0, StringComparison.OrdinalIgnoreCase);
if (num >= 0)
{
List<string> matchingDirectories = GetMatchingDirectories(@"Z:", matchPattern.Substring(0, num), 0);
string searchPattern = matchPattern.Substring(num + text.Length);
using (List<string>.Enumerator enumerator = matchingDirectories.GetEnumerator())
{
while (enumerator.MoveNext())
{
string current = enumerator.Current;
list.AddRange(Directory.GetFiles(current, searchPattern, SearchOption.AllDirectories));
}
return list;
}
}
int num2 = matchPattern.LastIndexOf(Path.DirectorySeparatorChar);
if (num2 >= 0)
{
List<string> matchingDirectories2 = GetMatchingDirectories(string.Empty, matchPattern.Substring(0, num2 + 1), 0);
string searchPattern2 = matchPattern.Substring(num2 + 1);
using (List<string>.Enumerator enumerator2 = matchingDirectories2.GetEnumerator())
{
while (enumerator2.MoveNext())
{
string current2 = enumerator2.Current;
try
{
list.AddRange(Directory.GetFiles(current2, searchPattern2, SearchOption.TopDirectoryOnly));
}
catch
{
}
}
return list;
}
}
try
{
list.AddRange(Directory.GetFiles(Directory.GetCurrentDirectory(), matchPattern, SearchOption.TopDirectoryOnly));
}
catch
{
}
return list;
}
private static List<string> GetMatchingDirectories(string rootDir, string pattern, int level)
{
if (level > 129)
{
return new List<string>();
}
List<string> list = new List<string>();
int num = pattern.IndexOf('*');
if (num >= 0)
{
int num2 = pattern.Substring(0, num).LastIndexOf(Path.DirectorySeparatorChar);
string text = (num2 >= 0) ? Path.Combine(rootDir, pattern.Substring(0, num2 + 1)) : rootDir;
if (text.Equals(string.Empty))
{
text = Directory.GetCurrentDirectory();
}
int num3 = pattern.IndexOf(Path.DirectorySeparatorChar, num);
if (num3 < 0)
{
num3 = pattern.Length;
}
string searchPattern = pattern.Substring(num2 + 1, num3 - num2 - 1);
try
{
string[] directories = Directory.GetDirectories(text, searchPattern, SearchOption.TopDirectoryOnly);
if (num3 < pattern.Length - 1)
{
string pattern2 = pattern.Substring(num3 + 1);
string[] array = directories;
for (int i = 0; i < array.Length; i++)
{
string rootDir2 = array[i];
list.AddRange(GetMatchingDirectories(rootDir2, pattern2, level + 1));
}
}
else
{
list.AddRange(directories);
}
return list;
}
catch
{
return list;
}
}
string text2 = Path.Combine(rootDir, pattern);
if (text2.Equals(string.Empty))
{
list.Add(Directory.GetCurrentDirectory());
}
else
{
if (Directory.Exists(text2))
{
list.Add(Path.GetFullPath(text2));
}
}
return list;
}
}
}