使用FindMatchingFiles工作流活动的MatchPattern属性

时间:2010-12-24 07:32:52

标签: tfs2010 build-process workflow-activity

我正在使用TFS 2010 Team Build自定义构建流程模板的默认工作流程。有一个名为FindMatchingFiles的活动允许搜索具有MatchPattern属性中定义的模式的特定文件。如果我只指定一个文件扩展名,它可以工作。例如:

String.Format("{0}\\**\\\*.msi", SourcesDirectory)

但我想包括* .exe。尝试以下模式,但它不起作用:

String.Format("{0}\\**\\\*.(msi|exe)", SourcesDirectory)

任何人都可以告诉我如何纠正它?

3 个答案:

答案 0 :(得分:14)

您可以使用String.Format("{0}\**\*.msi;{0}\**\*.exe", SourcesDirectory)

答案 1 :(得分:4)

FindMatchingFiles activityMatchPattern属性使用

  

Directory.GetFiles(String, String)方法的searchPattern参数支持的语法。

这意味着您无法组合多个扩展程序。您需要两次调用FindMatchingFiles活动。然后,您可以在使用它们时合并这两个调用的结果(即,如果结果为msiFilesexeFiles,则可以使用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;
        }
    }
}