예제 #1
0
        public List <GrepSearchResult> Search(string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            List <GrepSearchResult> searchResults = new List <GrepSearchResult>();
            SevenZipExtractor       extractor     = new SevenZipExtractor(file);
            string     tempFolder = Utils.FixFolderName(Utils.GetTempFolder()) + "dnGREP-Archive\\" + Utils.GetHash(file) + "\\";
            FileFilter filter     = FileFilter.ChangePath(tempFolder);

            // if the search pattern(s) only match archive files, need to include an 'any' file type to search inside the archive.
            // otherwise, keep the original pattern set so the user can specify what types of files to search inside the archive.
            var  patterns             = Utils.SplitPath(FileFilter.NamePatternToInclude).ToList();
            bool hasNonArchivePattern = patterns.Where(p => !Utils.IsArchiveExtension(Path.GetExtension(p))).Any();

            if (!hasNonArchivePattern)
            {
                patterns.Add(FileFilter.IsRegex ? ".*" : "*.*");
                filter = filter.ChangeIncludePattern(string.Join(";", patterns.ToArray()));
            }

            if (Directory.Exists(tempFolder))
            {
                Utils.DeleteFolder(tempFolder);
            }
            Directory.CreateDirectory(tempFolder);
            try
            {
                extractor.ExtractArchive(tempFolder);
                foreach (var innerFileName in Utils.GetFileListEx(filter))
                {
                    IGrepEngine engine           = GrepEngineFactory.GetSearchEngine(innerFileName, initParams, FileFilter);
                    var         innerFileResults = engine.Search(innerFileName, searchPattern, searchType, searchOptions, encoding);

                    if (innerFileResults.Count > 0)
                    {
                        using (FileStream reader = File.Open(innerFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            using (StreamReader streamReader = new StreamReader(reader))
                            {
                                foreach (var result in innerFileResults)
                                {
                                    if (Utils.CancelSearch)
                                    {
                                        break;
                                    }

                                    if (!result.HasSearchResults)
                                    {
                                        result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, initParams.LinesBefore, initParams.LinesAfter);
                                    }
                                }
                            }
                        searchResults.AddRange(innerFileResults);
                    }

                    if (Utils.CancelSearch)
                    {
                        break;
                    }
                }

                foreach (GrepSearchResult result in searchResults)
                {
                    result.FileNameDisplayed = file + "\\" + result.FileNameDisplayed.Substring(tempFolder.Length);
                    result.FileNameReal      = file;
                    result.ReadOnly          = true;
                }
            }
            catch (Exception ex)
            {
                logger.Log <Exception>(LogLevel.Error, string.Format("Failed to search inside archive '{0}'", file), ex);
            }
            return(searchResults);
        }