【问题标题】:Use MatchPattern property of FindMatchingFiles workflow activity使用 FindMatchingFiles 工作流活动的 MatchPattern 属性
【发布时间】:2014-06-25 20:39:34
【问题描述】:

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

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

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

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

谁能告诉我如何纠正它?

【问题讨论】:

    标签: build-process workflow-activity


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      FindMatchingFiles activityMatchPattern 属性使用

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

      这意味着您不能组合多个扩展。您需要调用FindMatchingFiles 活动两次。然后,您可以在使用这两个调用时组合它们的结果(即,如果您的结果是 msiFilesexeFiles,则可以使用 msiFiles.Concat(exeFiles) 作为 ForEach 的输入)。

      但是,正如您在 @antwoord's answer 中看到的那样,该活动实际上似乎接受分号分隔的模式列表,这与 Directory.GetFiles 不同。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-19
          • 2012-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多