Use MatchPattern property of FindMatchingFiles workflow activity

风格不统一 提交于 2019-12-18 15:33:04

问题


I'm customizing the default workflow of build process template using TFS 2010 Team Build. There is an activity named FindMatchingFiles allows to search for specific files with a pattern defined in MatchPattern property. It works if I only specify one file extension. Example:

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

But I would like to include *.exe as well. Trying following pattern but it doesn't work:

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

Anyone could show me how to correct it?


回答1:


You can use String.Format("{0}\**\*.msi;{0}\**\*.exe", SourcesDirectory)




回答2:


The FindMatchingFiles activity's MatchPattern property uses the

Syntax that is supported by the searchPattern argument of the Directory.GetFiles(String, String) method.

That means that you can't combine multiple extensions. You'll need to call the FindMatchingFiles activity twice. You can then combine the results of those two calls when you use them (i.e. if your results are msiFiles and exeFiles, you can use msiFiles.Concat(exeFiles) as the input to a ForEach).

However, as you can see with @antwoord's answer, the activity does actually seem to accept a semi-colon delimited list of patterns, unlike Directory.GetFiles.




回答3:


FindMatchingFiles has some strange search pattern. Here is the code (decompiled using ILSpy) so you can test your search patterns without having to kick off a new build.

It contains a hardcoded root dir at the following location (Z:)

List<string> matchingDirectories = GetMatchingDirectories(@"Z:", matchPattern.Substring(0, num), 0);

Code:

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;
        }
    }
}


来源:https://stackoverflow.com/questions/4524910/use-matchpattern-property-of-findmatchingfiles-workflow-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!