예제 #1
0
        internal static List <GrepSearchResult> Search(IGrepEngine engine, string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            if (engine == null)
            {
                throw new ArgumentNullException(nameof(engine));
            }

            if (string.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException(nameof(file));
            }

            string[] parts = file.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (!file.Contains(ArchiveDirectory.ArchiveSeparator) || parts.Length < 2)
            {
                return(new List <GrepSearchResult>());
            }
            else
            {
                string   diskFile          = parts.First();
                string   innerFileName     = parts.Last();
                string[] intermediateFiles = parts.Skip(1).Take(parts.Length - 2).ToArray();

                if (diskFile.Length > 260 && !diskFile.StartsWith(@"\\?\", StringComparison.InvariantCulture))
                {
                    diskFile = @"\\?\" + diskFile;
                }

                using (FileStream fileStream = File.Open(diskFile, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan))
                {
                    return(Search(engine, fileStream, file, diskFile, intermediateFiles, innerFileName, searchPattern, searchType, searchOptions, encoding));
                }
            }
        }
예제 #2
0
        public static IGrepEngine GetReplaceEngine(string fileName, GrepEngineInitParams param, FileFilter filter)
        {
            Debug.Assert(param != null);
            Debug.Assert(filter != null);

            LoadPlugins();

            string fileExtension = Path.GetExtension(fileName).ToLower().TrimStart('.');

            if (fileTypeEngines.ContainsKey(fileExtension) && !fileTypeEngines[fileExtension].IsSearchOnly)
            {
                IGrepEngine engine = fileTypeEngines[fileExtension].CreateEngine();
                if (engine != null && engine.Initialize(param, filter))
                {
                    loadedEngines.Add(engine);
                    return(engine);
                }
                else
                {
                    failedEngines[engine.GetType().Name] = "Failed to initialize the plugin. See error log for details.";
                    return(GetPlainTextEngine(fileExtension, param, filter));
                }
            }
            else
            {
                return(GetPlainTextEngine(fileExtension, param, filter));
            }
        }
예제 #3
0
        public List <GrepSearchResult> Search(string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            string tempFolder = Path.Combine(Utils.GetTempFolder(), "dnGREP-PDF");

            try
            {
                // Extract text
                string tempFile = ExtractText(file);
                if (!File.Exists(tempFile))
                {
                    throw new ApplicationException("pdftotext failed to create text file.");
                }

                // GrepCore cannot check encoding of the original pdf file. If the encoding parameter is not default
                // then it is the user-specified code page.  If the encoding parameter *is* the default,
                // then it most likely not been set, so get the encoding of the extracted text file:
                if (encoding == Encoding.Default)
                {
                    encoding = Utils.GetFileEncoding(tempFile);
                }

                IGrepEngine             engine  = GrepEngineFactory.GetSearchEngine(tempFile, initParams, FileFilter);
                List <GrepSearchResult> results = engine.Search(tempFile, searchPattern, searchType, searchOptions, encoding);

                if (results.Count > 0)
                {
                    using (FileStream reader = File.Open(tempFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (StreamReader streamReader = new StreamReader(reader, encoding))
                        {
                            foreach (var result in results)
                            {
                                result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, initParams.LinesBefore, initParams.LinesAfter);
                            }
                        }

                    foreach (GrepSearchResult result in results)
                    {
                        result.ReadOnly = true;
                        if (file.Contains(tempFolder))
                        {
                            result.FileNameDisplayed = file.Substring(tempFolder.Length + 1);
                        }
                        else
                        {
                            result.FileNameDisplayed = file;
                        }
                        result.FileNameReal = file;
                    }
                }

                GrepEngineFactory.ReturnToPool(tempFile, engine);

                return(results);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"Failed to search inside PDF file: {ex.Message}");
                return(new List <GrepSearchResult>());
            }
        }
예제 #4
0
        public List <GrepSearchResult> Search(string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            string tempFolder = Path.Combine(Utils.GetTempFolder(), "dnGREP-PDF");

            try
            {
                // Extract text
                string tempFile = extractText(file);
                if (!File.Exists(tempFile))
                {
                    throw new ApplicationException("pdftotext failed to create text file.");
                }

                IGrepEngine             engine  = GrepEngineFactory.GetSearchEngine(tempFile, initParams, FileFilter);
                List <GrepSearchResult> results = engine.Search(tempFile, searchPattern, searchType, searchOptions, encoding);

                if (results.Count > 0)
                {
                    using (FileStream reader = File.Open(tempFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (StreamReader streamReader = new StreamReader(reader))
                        {
                            foreach (var result in results)
                            {
                                result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, initParams.LinesBefore, initParams.LinesAfter);
                            }
                        }

                    foreach (GrepSearchResult result in results)
                    {
                        result.ReadOnly = true;
                        if (file.Contains(tempFolder))
                        {
                            result.FileNameDisplayed = file.Substring(tempFolder.Length + 1);
                        }
                        else
                        {
                            result.FileNameDisplayed = file;
                        }
                        result.FileNameReal = file;
                    }
                }

                GrepEngineFactory.ReturnToPool(tempFile, engine);

                return(results);
            }
            catch (Exception ex)
            {
                logger.Log <Exception>(LogLevel.Error, "Failed to search inside Pdf file", ex);
                return(new List <GrepSearchResult>());
            }
        }
예제 #5
0
        public static IGrepEngine GetSearchEngine(string fileName, GrepEngineInitParams param, FileFilter filter, SearchType searchType)
        {
            Debug.Assert(param != null);
            Debug.Assert(filter != null);

            LoadPlugins();

            string fileExtension = Path.GetExtension(fileName).ToLower().TrimStart('.');

            lock (lockObj)
            {
                if (searchType == SearchType.Hex)
                {
                    return(GetHexEngine(param, filter));
                }

                IGrepEngine poolEngine = FetchFromPool(fileExtension);
                if (poolEngine != null)
                {
                    poolEngine.Initialize(param, filter);
                    return(poolEngine);
                }

                if (ArchiveDirectory.Extensions.Contains(fileExtension))
                {
                    return(GetArchiveEngine(fileExtension, param, filter));
                }

                if (fileTypeEngines.ContainsKey(fileExtension))
                {
                    IGrepEngine engine = fileTypeEngines[fileExtension].CreateEngine();
                    if (engine != null && engine.Initialize(param, filter))
                    {
                        loadedEngines.Add(engine);
                        logger.Debug(string.Format("Using plugin: {0} for extension {1}", engine.ToString(), fileExtension));
                        return(engine);
                    }
                    else
                    {
                        logger.Debug(string.Format("File type engines failed to initialize: {0}, using plainTextEngine", fileExtension));
                        failedEngines[engine.GetType().Name] = "Failed to initialize the plugin. See error log for details.";
                        return(GetPlainTextEngine(fileExtension, param, filter));
                    }
                }
                else
                {
                    logger.Debug(string.Format("File type engines has no key for: {0}, using plainTextEngine", fileExtension));
                    return(GetPlainTextEngine(fileExtension, param, filter));
                }
            }
        }
예제 #6
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);
            GrepEnginePlainText     plainTextEngine = new GrepEnginePlainText();

            plainTextEngine.Initialize(new GrepEngineInitParams(showLinesInContext, linesBefore, linesAfter, fuzzyMatchThreshold));
            string tempFolder = Utils.FixFolderName(Utils.GetTempFolder()) + "dnGREP-Archive\\" + Utils.GetHash(file) + "\\";

            if (Directory.Exists(tempFolder))
            {
                Utils.DeleteFolder(tempFolder);
            }
            Directory.CreateDirectory(tempFolder);
            try
            {
                extractor.ExtractArchive(tempFolder);
                foreach (string archiveFileName in Directory.GetFiles(tempFolder, "*.*", SearchOption.AllDirectories))
                {
                    IGrepEngine engine           = GrepEngineFactory.GetSearchEngine(archiveFileName, new GrepEngineInitParams(showLinesInContext, linesBefore, linesAfter, fuzzyMatchThreshold));
                    var         innerFileResults = engine.Search(archiveFileName, searchPattern, searchType, searchOptions, encoding);

                    using (FileStream reader = File.Open(archiveFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (StreamReader streamReader = new StreamReader(reader))
                        {
                            foreach (var result in innerFileResults)
                            {
                                if (!result.HasSearchResults)
                                {
                                    result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, linesBefore, linesAfter);
                                }
                            }
                        }
                    searchResults.AddRange(innerFileResults);
                }

                foreach (GrepSearchResult result in searchResults)
                {
                    result.FileNameDisplayed = file + "\\" + result.FileNameDisplayed.Substring(tempFolder.Length);
                    result.FileNameReal      = file;
                    result.ReadOnly          = true;
                }
            }
            catch (Exception ex)
            {
                logger.LogException(LogLevel.Error, "Failed to search inside archive.", ex);
            }
            return(searchResults);
        }
예제 #7
0
        private static IGrepEngine FetchFromPool(string fileExtension)
        {
            IGrepEngine engine = null;

            if (poolKeys.TryGetValue(fileExtension, out string poolKey))
            {
                if (GrepEngineFactory.pooledEngines.TryGetValue(poolKey, out Queue <IGrepEngine> pooledEngines))
                {
                    if (pooledEngines.Count > 0)
                    {
                        engine = pooledEngines.Dequeue();
                    }
                }
            }
            return(engine);
        }
예제 #8
0
        public static void ReturnToPool(string fileName, IGrepEngine engine)
        {
            lock (lockObj)
            {
                string fileExtension = Path.GetExtension(fileName).ToLower().TrimStart('.');
                if (poolKeys.TryGetValue(fileExtension, out string poolKey))
                {
                    if (!GrepEngineFactory.pooledEngines.TryGetValue(poolKey, out Queue <IGrepEngine> pooledEngines))
                    {
                        pooledEngines = new Queue <IGrepEngine>();
                        GrepEngineFactory.pooledEngines.Add(poolKey, pooledEngines);
                    }

                    pooledEngines.Enqueue(engine);
                }
            }
        }
예제 #9
0
        public IGrepEngine CreateEngine()
        {
            IGrepEngine engine = null;

            try
            {
                if (pluginType != null)
                {
                    engine = (IGrepEngine)Activator.CreateInstance(pluginType);
                }
            }
            catch (Exception ex)
            {
                logger.Log <Exception>(LogLevel.Error, "Failed to create engine " + Path.GetFileNameWithoutExtension(DllFilePath), ex);
            }
            return(engine);
        }
예제 #10
0
        private static IGrepEngine GetPlainTextEngine(string fileExtension, GrepEngineInitParams param, FileFilter filter)
        {
            if (!poolKeys.ContainsKey(fileExtension))
            {
                poolKeys.Add(fileExtension, "GrepEnginePlainText");
            }

            IGrepEngine poolEngine = FetchFromPool(fileExtension);

            if (poolEngine != null)
            {
                poolEngine.Initialize(param, filter);
                return(poolEngine);
            }

            IGrepEngine engine = new GrepEnginePlainText();

            loadedEngines.Add(engine);
            engine.Initialize(param, filter);
            return(engine);
        }
예제 #11
0
        public List <GrepSearchResult> Search(string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            try
            {
                // Extract text
                string tempFile = extractText(file);
                if (!File.Exists(tempFile))
                {
                    throw new ApplicationException("pdftotext failed to create text file.");
                }

                IGrepEngine             engine  = GrepEngineFactory.GetSearchEngine(tempFile, new GrepEngineInitParams(showLinesInContext, linesBefore, linesAfter, fuzzyMatchThreshold));
                List <GrepSearchResult> results = engine.Search(tempFile, searchPattern, searchType, searchOptions, encoding);

                using (FileStream reader = File.Open(tempFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    using (StreamReader streamReader = new StreamReader(reader))
                    {
                        foreach (var result in results)
                        {
                            result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, linesBefore, linesAfter);
                        }
                    }

                foreach (GrepSearchResult result in results)
                {
                    result.ReadOnly          = true;
                    result.FileNameDisplayed = file;
                    result.FileNameReal      = file;
                }

                return(results);
            }
            catch (Exception ex)
            {
                logger.LogException(LogLevel.Error, "Failed to search inside Pdf file", ex);
                return(new List <GrepSearchResult>());
            }
        }
예제 #12
0
        public int Replace(IEnumerable <string> files, SearchType searchType, string baseFolder, string searchPattern, string replacePattern, GrepSearchOption searchOptions, int codePage)
        {
            string tempFolder = Utils.GetTempFolder();

            if (Directory.Exists(tempFolder))
            {
                Utils.DeleteFolder(tempFolder);
            }
            Directory.CreateDirectory(tempFolder);

            if (files == null || !Directory.Exists(tempFolder) || !Directory.Exists(baseFolder))
            {
                return(0);
            }

            baseFolder     = Utils.FixFolderName(baseFolder);
            tempFolder     = Utils.FixFolderName(tempFolder);
            replacePattern = Utils.ReplaceSpecialCharacters(replacePattern);

            int processedFiles = 0;

            Utils.CancelSearch = false;

            try
            {
                foreach (string file in files)
                {
                    if (!file.Contains(baseFolder))
                    {
                        continue;
                    }

                    string      tempFileName = file.Replace(baseFolder, tempFolder);
                    IGrepEngine engine       = GrepEngineFactory.GetReplaceEngine(file, searchParams);

                    try
                    {
                        processedFiles++;
                        // Copy file
                        Utils.CopyFile(file, tempFileName, true);
                        Utils.DeleteFile(file);

                        Encoding encoding = null;
                        if (codePage == -1)
                        {
                            encoding = Utils.GetFileEncoding(tempFileName);
                        }
                        else
                        {
                            encoding = Encoding.GetEncoding(codePage);
                        }


                        if (Utils.CancelSearch)
                        {
                            break;
                        }

                        if (!engine.Replace(tempFileName, file, searchPattern, replacePattern, searchType, searchOptions, encoding))
                        {
                            throw new ApplicationException("Replace failed for file: " + file);
                        }

                        if (!Utils.CancelSearch && ProcessedFile != null)
                        {
                            ProcessedFile(this, new ProgressStatus(processedFiles, null));
                        }


                        File.SetAttributes(file, File.GetAttributes(tempFileName));

                        if (Utils.CancelSearch)
                        {
                            // Replace the file
                            Utils.DeleteFile(file);
                            Utils.CopyFile(tempFileName, file, true);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogException(LogLevel.Error, ex.Message, ex);
                        try
                        {
                            // Replace the file
                            if (File.Exists(tempFileName) && File.Exists(file))
                            {
                                Utils.DeleteFile(file);
                                Utils.CopyFile(tempFileName, file, true);
                            }
                        }
                        catch
                        {
                            // DO NOTHING
                        }
                        return(-1);
                    }
                }
            }
            finally
            {
                GrepEngineFactory.UnloadEngines();
            }

            return(processedFiles);
        }
예제 #13
0
        /// <summary>
        /// Searches folder for files whose content matches regex
        /// </summary>
        /// <param name="files">Files to search in. If one of the files does not exist or is open, it is skipped.</param>
        /// <param name="searchRegex">Regex pattern</param>
        /// <returns>List of results. If nothing is found returns empty list</returns>
        public List <GrepSearchResult> Search(IEnumerable <string> files, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            List <GrepSearchResult> searchResults = new List <GrepSearchResult>();

            if (files == null)
            {
                return(searchResults);
            }

            Utils.CancelSearch = false;

            if (searchPattern == null || searchPattern.Trim() == "")
            {
                foreach (string file in files)
                {
                    searchResults.Add(new GrepSearchResult(file, searchPattern, null));
                    if ((searchOptions & GrepSearchOption.StopAfterFirstMatch) == GrepSearchOption.StopAfterFirstMatch)
                    {
                        break;
                    }
                }

                if (ProcessedFile != null)
                {
                    ProcessedFile(this, new ProgressStatus(searchResults.Count, searchResults));
                }

                return(searchResults);
            }
            else
            {
                int processedFiles = 0;

                try
                {
                    foreach (string file in files)
                    {
                        try
                        {
                            IGrepEngine engine = GrepEngineFactory.GetSearchEngine(file, SearchParams);

                            processedFiles++;

                            Encoding encoding = null;
                            if (codePage == -1)
                            {
                                encoding = Utils.GetFileEncoding(file);
                            }
                            else
                            {
                                encoding = Encoding.GetEncoding(codePage);
                            }


                            if (Utils.CancelSearch)
                            {
                                return(searchResults);
                            }

                            List <GrepSearchResult> fileSearchResults = engine.Search(file, searchPattern, searchType, searchOptions, encoding);

                            if (fileSearchResults != null && fileSearchResults.Count > 0)
                            {
                                searchResults.AddRange(fileSearchResults);
                            }

                            if (ProcessedFile != null)
                            {
                                ProcessedFile(this, new ProgressStatus(processedFiles, fileSearchResults));
                            }
                        }
                        catch (Exception ex)
                        {
                            logger.LogException(LogLevel.Error, ex.Message, ex);
                            searchResults.Add(new GrepSearchResult(file, searchPattern, ex.Message, false));
                            if (ProcessedFile != null)
                            {
                                List <GrepSearchResult> _results = new List <GrepSearchResult>();
                                _results.Add(new GrepSearchResult(file, searchPattern, ex.Message, false));
                                ProcessedFile(this, new ProgressStatus(processedFiles, _results));
                            }
                        }

                        if ((searchOptions & GrepSearchOption.StopAfterFirstMatch) == GrepSearchOption.StopAfterFirstMatch && searchResults.Count > 0)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    GrepEngineFactory.UnloadEngines();
                }

                return(searchResults);
            }
        }
예제 #14
0
        public List <GrepSearchResult> Search(Stream input, string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            List <GrepSearchResult> searchResults = new List <GrepSearchResult>();

            var includeRegexPatterns = new List <Regex>();
            var excludeRegexPatterns = new List <Regex>();

            Utils.PrepareFilters(FileFilter, includeRegexPatterns, excludeRegexPatterns);

            List <string> hiddenDirectories = new List <string>();

            try
            {
                using (SevenZipExtractor extractor = new SevenZipExtractor(input))
                {
                    foreach (var fileInfo in extractor.ArchiveFileData)
                    {
                        var    attr          = (FileAttributes)fileInfo.Attributes;
                        string innerFileName = fileInfo.FileName;

                        if (fileInfo.IsDirectory)
                        {
                            if (!FileFilter.IncludeHidden && attr.HasFlag(FileAttributes.Hidden) && !hiddenDirectories.Contains(innerFileName))
                            {
                                hiddenDirectories.Add(innerFileName);
                            }

                            continue;
                        }

                        if (CheckHidden(FileFilter, attr) &&
                            CheckHidden(FileFilter, innerFileName, hiddenDirectories) &&
                            CheckSize(FileFilter, fileInfo.Size) &&
                            CheckDate(FileFilter, fileInfo) &&
                            IsPatternMatch(innerFileName, includeRegexPatterns) &&
                            !IsPatternMatch(innerFileName, excludeRegexPatterns))
                        {
                            using (Stream stream = new MemoryStream())
                            {
                                extractor.ExtractFile(innerFileName, stream);
                                stream.Seek(0, SeekOrigin.Begin);

                                if (CheckBinary(FileFilter, stream))
                                {
                                    IGrepEngine engine           = GrepEngineFactory.GetSearchEngine(innerFileName, initParams, FileFilter);
                                    var         innerFileResults = engine.Search(stream, innerFileName, searchPattern, searchType, searchOptions, encoding);

                                    if (innerFileResults.Count > 0)
                                    {
                                        using (Stream readStream = new MemoryStream())
                                        {
                                            extractor.ExtractFile(innerFileName, readStream);
                                            readStream.Seek(0, SeekOrigin.Begin);
                                            using (StreamReader streamReader = new StreamReader(readStream))
                                            {
                                                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;
                    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);
        }
예제 #15
0
파일: GrepPlugin.cs 프로젝트: wqssyq/dnGrep
        public bool LoadPluginSettings()
        {
            if (pluginFilePath != null && File.Exists(pluginFilePath))
            {
                try
                {
                    foreach (string line in File.ReadAllLines(pluginFilePath))
                    {
                        string[] tokens = line.Split('=');
                        if (tokens.Length != 2)
                        {
                            continue;
                        }

                        switch (tokens[0].Trim().ToUpper())
                        {
                        case "FILE":
                            DllFilePath = tokens[1].Trim();
                            break;

                        case "ENABLED":
                            Enabled = Utils.ParseBoolean(tokens[1].Trim(), true);
                            break;

                        case "EXTENSIONS":
                            Extensions.Clear();
                            foreach (string extension in tokens[1].Trim().Split(','))
                            {
                                Extensions.Add(extension.Trim().ToLower());
                            }
                            break;
                        }
                    }

                    string tempDllFilePath = DllFilePath;
                    if (!File.Exists(tempDllFilePath))
                    {
                        tempDllFilePath = Path.GetDirectoryName(pluginFilePath) + "\\" + tempDllFilePath;
                    }

                    if (File.Exists(tempDllFilePath))
                    {
                        Assembly assembly = Assembly.LoadFile(tempDllFilePath);
                        Type[]   types    = assembly.GetTypes();
                        foreach (Type type in types)
                        {
                            if (type.GetInterface("IGrepEngine") != null)
                            {
                                IGrepEngine engine = (IGrepEngine)Activator.CreateInstance(type);
                                Engine = engine;
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            if (Engine != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #16
0
        private void Search(string file, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            try
            {
                ProcessedFile(this, new ProgressStatus(true, processedFilesCount, foundfilesCount, null, file));

                IGrepEngine engine = GrepEngineFactory.GetSearchEngine(file, SearchParams, FileFilter);

                Interlocked.Increment(ref processedFilesCount);

                Encoding encoding = Encoding.Default;
                if (codePage > -1)
                {
                    encoding = Encoding.GetEncoding(codePage);
                }
                else if (!Utils.IsBinary(file) && !Utils.IsPdfFile(file))
                {
                    encoding = Utils.GetFileEncoding(file);
                }

                if (Utils.CancelSearch)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                    return;
                }

                List <GrepSearchResult> fileSearchResults = engine.Search(file, searchPattern, searchType, searchOptions, encoding);

                if (fileSearchResults != null && fileSearchResults.Count > 0)
                {
                    AddSearchResults(fileSearchResults);
                }
                int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                Interlocked.Add(ref foundfilesCount, hits);

                ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));

                GrepEngineFactory.ReturnToPool(file, engine);
            }
            catch (Exception ex)
            {
                logger.Log <Exception>(LogLevel.Error, ex.Message, ex);
                AddSearchResult(new GrepSearchResult(file, searchPattern, ex.Message, false));
                if (ProcessedFile != null)
                {
                    List <GrepSearchResult> _results = new List <GrepSearchResult>();
                    _results.Add(new GrepSearchResult(file, searchPattern, ex.Message, false));
                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, _results, file));
                }
            }
            finally
            {
                if ((searchOptions & GrepSearchOption.StopAfterFirstMatch) == GrepSearchOption.StopAfterFirstMatch && searchResults.Count > 0)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                }
            }
        }
예제 #17
0
        public int Replace(Dictionary <string, string> files, SearchType searchType, string searchPattern, string replacePattern, GrepSearchOption searchOptions, int codePage)
        {
            string tempFolder = Utils.GetTempFolder();

            if (files == null || files.Count == 0 || !Directory.Exists(tempFolder))
            {
                return(0);
            }

            replacePattern = Utils.ReplaceSpecialCharacters(replacePattern);

            int processedFiles = 0;

            Utils.CancelSearch = false;
            string tempFileName = null;

            try
            {
                foreach (string file in files.Keys)
                {
                    ProcessedFile(this, new ProgressStatus(true, processedFiles, processedFiles, null, file));

                    // the value in the files dictionary is the temp file name assigned by
                    // the caller for any possible Undo operation
                    tempFileName = Path.Combine(tempFolder, files[file]);
                    IGrepEngine engine = GrepEngineFactory.GetReplaceEngine(file, SearchParams, FileFilter);

                    try
                    {
                        processedFiles++;
                        // Copy file
                        Utils.CopyFile(file, tempFileName, true);
                        Utils.DeleteFile(file);

                        Encoding encoding = Encoding.Default;
                        if (codePage > -1)
                        {
                            encoding = Encoding.GetEncoding(codePage);
                        }
                        else if (!Utils.IsBinary(tempFileName))
                        {
                            encoding = Utils.GetFileEncoding(tempFileName);
                        }

                        if (Utils.CancelSearch)
                        {
                            break;
                        }

                        if (!engine.Replace(tempFileName, file, searchPattern, replacePattern, searchType, searchOptions, encoding))
                        {
                            throw new ApplicationException("Replace failed for file: " + file);
                        }

                        if (!Utils.CancelSearch)
                        {
                            ProcessedFile(this, new ProgressStatus(false, processedFiles, processedFiles, null, file));
                        }


                        File.SetAttributes(file, File.GetAttributes(tempFileName));

                        GrepEngineFactory.ReturnToPool(file, engine);

                        if (Utils.CancelSearch)
                        {
                            // Replace the file
                            Utils.DeleteFile(file);
                            Utils.CopyFile(tempFileName, file, true);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Log <Exception>(LogLevel.Error, ex.Message, ex);
                        try
                        {
                            // Replace the file
                            if (File.Exists(tempFileName) && File.Exists(file))
                            {
                                Utils.DeleteFile(file);
                                Utils.CopyFile(tempFileName, file, true);
                            }
                        }
                        catch
                        {
                            // DO NOTHING
                        }
                        return(-1);
                    }
                }
            }
            finally
            {
                GrepEngineFactory.UnloadEngines();
            }

            return(processedFiles);
        }
예제 #18
0
파일: GrepCore.cs 프로젝트: dnGrep/dnGrep
        private void Search(string file, SearchType searchType, string searchPattern, GrepSearchOption searchOptions, int codePage)
        {
            try
            {
                ProcessedFile(this, new ProgressStatus(true, processedFilesCount, foundfilesCount, null, file));

                bool isArchive = Utils.IsArchive(file);

                Encoding encoding = Encoding.Default;
                if (codePage > -1)
                {
                    encoding = Encoding.GetEncoding(codePage);
                }
                else if (!isArchive && !Utils.IsBinary(file) && !Utils.IsPdfFile(file))
                {
                    encoding = Utils.GetFileEncoding(file);
                }

                if (Utils.CancelSearch)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                    return;
                }

                IGrepEngine engine = GrepEngineFactory.GetSearchEngine(file, SearchParams, FileFilter, searchType);

                if (isArchive && engine is ArchiveEngine archiveEngine)
                {
                    archiveEngine.SetSearchOptions(FileFilter, SearchParams);
                    archiveEngine.StartingFileSearch += ArchiveEngine_StartingFileSearch;

                    foreach (var fileSearchResults in archiveEngine.Search(file, searchPattern, searchType, searchOptions, encoding))
                    {
                        if (fileSearchResults != null && fileSearchResults.Count > 0)
                        {
                            AddSearchResults(fileSearchResults);
                        }
                        int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                        Interlocked.Add(ref foundfilesCount, hits);

                        ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));
                    }
                    archiveEngine.StartingFileSearch -= ArchiveEngine_StartingFileSearch;
                }
                else
                {
                    Interlocked.Increment(ref processedFilesCount);

                    var fileSearchResults = engine.Search(file, searchPattern, searchType, searchOptions, encoding).ToList();

                    if (fileSearchResults != null && fileSearchResults.Count > 0)
                    {
                        AddSearchResults(fileSearchResults);
                    }
                    int hits = fileSearchResults.Where(r => r.IsSuccess).Count();
                    Interlocked.Add(ref foundfilesCount, hits);

                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, fileSearchResults, file));
                }

                GrepEngineFactory.ReturnToPool(file, engine);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Failed in Search");
                AddSearchResult(new GrepSearchResult(file, searchPattern, ex.Message, false));
                if (ProcessedFile != null)
                {
                    List <GrepSearchResult> _results = new List <GrepSearchResult>
                    {
                        new GrepSearchResult(file, searchPattern, ex.Message, false)
                    };
                    ProcessedFile(this, new ProgressStatus(false, processedFilesCount, foundfilesCount, _results, file));
                }
            }
            finally
            {
                if (searchOptions.HasFlag(GrepSearchOption.StopAfterFirstMatch) && searchResults.Count > 0)
                {
                    if (cancellationTokenSource != null)
                    {
                        cancellationTokenSource.Cancel();
                    }
                }
            }
        }
예제 #19
0
        public int Replace(IEnumerable <string> files, SearchType searchType, string searchPattern, string replacePattern, GrepSearchOption searchOptions, int codePage)
        {
            string tempFolder = Utils.GetTempFolder();

            if (files == null || !Directory.Exists(tempFolder))
            {
                return(0);
            }

            replacePattern = Utils.ReplaceSpecialCharacters(replacePattern);

            int processedFiles = 0;

            Utils.CancelSearch = false;
            string tempFileName = null;

            try
            {
                foreach (string file in files)
                {
                    ProcessedFile(this, new ProgressStatus(processedFiles, null, file));

                    tempFileName = Path.Combine(tempFolder, Path.GetFileName(file));
                    IGrepEngine engine = GrepEngineFactory.GetReplaceEngine(file, SearchParams, FileFilter);

                    try
                    {
                        processedFiles++;
                        // Copy file
                        Utils.CopyFile(file, tempFileName, true);
                        Utils.DeleteFile(file);

                        Encoding encoding = Encoding.Default;
                        if (codePage > -1)
                        {
                            encoding = Encoding.GetEncoding(codePage);
                        }
                        else if (!Utils.IsBinary(file))
                        {
                            encoding = Utils.GetFileEncoding(tempFileName);
                        }

                        if (Utils.CancelSearch)
                        {
                            break;
                        }

                        if (!engine.Replace(tempFileName, file, searchPattern, replacePattern, searchType, searchOptions, encoding))
                        {
                            throw new ApplicationException("Replace failed for file: " + file);
                        }

                        if (!Utils.CancelSearch)
                        {
                            ProcessedFile(this, new ProgressStatus(processedFiles, null, file));
                        }


                        File.SetAttributes(file, File.GetAttributes(tempFileName));

                        if (Utils.CancelSearch)
                        {
                            // Replace the file
                            Utils.DeleteFile(file);
                            Utils.CopyFile(tempFileName, file, true);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Log <Exception>(LogLevel.Error, ex.Message, ex);
                        try
                        {
                            // Replace the file
                            if (File.Exists(tempFileName) && File.Exists(file))
                            {
                                Utils.DeleteFile(file);
                                Utils.CopyFile(tempFileName, file, true);
                            }
                        }
                        catch
                        {
                            // DO NOTHING
                        }
                        return(-1);
                    }
                    finally
                    {
                        try
                        {
                            if (!string.IsNullOrWhiteSpace(tempFileName))
                            {
                                Utils.DeleteFile(tempFileName);
                            }
                        }
                        catch
                        {
                            // DO NOTHING
                        }
                    }
                }
            }
            finally
            {
                GrepEngineFactory.UnloadEngines();
            }

            return(processedFiles);
        }
예제 #20
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);
        }
예제 #21
0
        public List <GrepSearchResult> Search(Stream input, string file, string searchPattern, SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            List <GrepSearchResult> searchResults = new List <GrepSearchResult>();

            var filter = FileFilter.ToStandardFilter();

            var includeRegexPatterns = new List <Regex>();
            var excludeRegexPatterns = new List <Regex>();

            Utils.PrepareFilters(filter, includeRegexPatterns, excludeRegexPatterns);

            List <string> hiddenDirectories = new List <string>();

            try
            {
                using (SevenZipExtractor extractor = new SevenZipExtractor(input))
                {
                    foreach (var fileInfo in extractor.ArchiveFileData)
                    {
                        var    attr          = (FileAttributes)fileInfo.Attributes;
                        string innerFileName = fileInfo.FileName;

                        if (fileInfo.IsDirectory)
                        {
                            if (!filter.IncludeHidden && attr.HasFlag(FileAttributes.Hidden) && !hiddenDirectories.Contains(innerFileName))
                            {
                                hiddenDirectories.Add(innerFileName);
                            }

                            continue;
                        }

                        if (CheckHidden(filter, attr) &&
                            CheckHidden(filter, innerFileName, hiddenDirectories) &&
                            CheckSize(filter, fileInfo.Size) &&
                            CheckDate(filter, fileInfo) &&
                            IsPatternMatch(innerFileName, includeRegexPatterns) &&
                            !IsPatternMatch(innerFileName, excludeRegexPatterns))
                        {
                            using (Stream stream = new MemoryStream())
                            {
                                extractor.ExtractFile(innerFileName, stream);
                                stream.Seek(0, SeekOrigin.Begin);

                                if (CheckBinary(filter, stream))
                                {
                                    // Need to check the encoding of each file in the archive. If the encoding parameter is not default
                                    // then it is the user-specified code page.  If the encoding parameter *is* the default,
                                    // then it most likely not been set, so get the encoding of the extracted text file:
                                    if (encoding == Encoding.Default && !Utils.IsBinary(stream))
                                    {
                                        stream.Seek(0, SeekOrigin.Begin);
                                        encoding = Utils.GetFileEncoding(stream);
                                    }

                                    IGrepEngine engine           = GrepEngineFactory.GetSearchEngine(innerFileName, initParams, filter);
                                    var         innerFileResults = engine.Search(stream, innerFileName, searchPattern, searchType, searchOptions, encoding);

                                    if (innerFileResults.Count > 0)
                                    {
                                        using (Stream readStream = new MemoryStream())
                                        {
                                            extractor.ExtractFile(innerFileName, readStream);
                                            readStream.Seek(0, SeekOrigin.Begin);
                                            using (StreamReader streamReader = new StreamReader(readStream, encoding))
                                            {
                                                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);
                                        }
                                    }

                                    GrepEngineFactory.ReturnToPool(innerFileName, engine);
                                }
                                if (Utils.CancelSearch)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (GrepSearchResult result in searchResults)
                {
                    result.FileNameDisplayed = file + "\\" + result.FileNameDisplayed;
                    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);
        }
예제 #22
0
        public int Replace(IEnumerable <ReplaceDef> files, SearchType searchType, string searchPattern, string replacePattern, GrepSearchOption searchOptions, int codePage)
        {
            string tempFolder = Utils.GetTempFolder();

            if (files == null || !files.Any() || !Directory.Exists(tempFolder))
            {
                return(0);
            }

            GrepEngineBase.ResetGuidxCache();

            replacePattern = Utils.ReplaceSpecialCharacters(replacePattern);

            int processedFiles = 0;

            Utils.CancelSearch = false;
            string tempFileName = null;

            try
            {
                foreach (var item in files)
                {
                    ProcessedFile(this, new ProgressStatus(true, processedFiles, processedFiles, null, item.OrginalFile));

                    // the value in the files dictionary is the temp file name assigned by
                    // the caller for any possible Undo operation
                    tempFileName = Path.Combine(tempFolder, item.BackupName);
                    IGrepEngine engine = GrepEngineFactory.GetReplaceEngine(item.OrginalFile, SearchParams, FileFilter);

                    try
                    {
                        processedFiles++;
                        // Copy file
                        Utils.CopyFile(item.OrginalFile, tempFileName, true);
                        Utils.DeleteFile(item.OrginalFile);

                        Encoding encoding = Encoding.Default;
                        if (codePage > -1)
                        {
                            encoding = Encoding.GetEncoding(codePage);
                        }
                        else if (!Utils.IsBinary(tempFileName))
                        {
                            encoding = Utils.GetFileEncoding(tempFileName);
                        }

                        // The UTF-8 encoding returned from Encoding.GetEncoding("utf-8") includes the BOM - see Encoding.GetPreamble()
                        // If this file does not have the BOM, then change to an encoder without the BOM so the BOM is not added in
                        // the replace operation
                        if (encoding is UTF8Encoding && !Utils.HasUtf8ByteOrderMark(tempFileName))
                        {
                            encoding = new UTF8Encoding(false);
                        }

                        if (Utils.CancelSearch)
                        {
                            break;
                        }

                        if (!engine.Replace(tempFileName, item.OrginalFile, searchPattern, replacePattern, searchType, searchOptions, encoding, item.ReplaceItems))
                        {
                            throw new ApplicationException("Replace failed for file: " + item.OrginalFile);
                        }

                        if (!Utils.CancelSearch)
                        {
                            ProcessedFile(this, new ProgressStatus(false, processedFiles, processedFiles, null, item.OrginalFile));
                        }


                        File.SetAttributes(item.OrginalFile, File.GetAttributes(tempFileName));

                        GrepEngineFactory.ReturnToPool(item.OrginalFile, engine);

                        if (Utils.CancelSearch)
                        {
                            // Replace the file
                            Utils.DeleteFile(item.OrginalFile);
                            Utils.CopyFile(tempFileName, item.OrginalFile, true);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Log <Exception>(LogLevel.Error, ex.Message, ex);
                        try
                        {
                            // Replace the file
                            if (File.Exists(tempFileName) && File.Exists(item.OrginalFile))
                            {
                                Utils.DeleteFile(item.OrginalFile);
                                Utils.CopyFile(tempFileName, item.OrginalFile, true);
                            }
                        }
                        catch
                        {
                            // DO NOTHING
                        }
                        return(-1);
                    }
                }
            }
            finally
            {
                GrepEngineFactory.UnloadEngines();
            }

            return(processedFiles);
        }
예제 #23
0
        private List <GrepSearchResult> SearchInnerFile(SevenZipExtractor extractor, int index,
                                                        FileFilter fileFilter, FileData fileData, string innerFileName, string searchPattern,
                                                        SearchType searchType, GrepSearchOption searchOptions, Encoding encoding)
        {
            List <GrepSearchResult> innerFileResults = null;

            try
            {
                using (Stream stream = new MemoryStream(4096))
                {
                    extractor.ExtractFile(index, stream);
                    stream.Seek(0, SeekOrigin.Begin);

                    if (!ArchiveDirectory.IncludeFileStream(stream,
                                                            fileFilter, fileData, true, includeShebangPatterns))
                    {
                        return(innerFileResults);
                    }

                    // The IncludeFileStream method determined the encoding of the file in the archive.
                    // If the encoding parameter is not default then it is the user-specified code page.
                    // If the encoding parameter *is* the default, then it most likely not been set, so
                    // use the encoding of the extracted text file
                    if (encoding == Encoding.Default && !fileData.IsBinary)
                    {
                        encoding = fileData.Encoding;
                    }

                    StartingFileSearch?.Invoke(this, new DataEventArgs <string>(innerFileName));

                    IGrepEngine engine = GrepEngineFactory.GetSearchEngine(innerFileName, searchParams, fileFilter, searchType);
                    innerFileResults = engine.Search(stream, innerFileName, searchPattern, searchType, searchOptions, encoding);

                    if (innerFileResults.Any())
                    {
                        if (precacheResults)
                        {
                            // pre-cache the search results since the text is available.
                            // user has set the option to auto-expand the results tree, so all the
                            // search results data will be needed, and this will save reopening the
                            // archive for each file
                            stream.Seek(0, SeekOrigin.Begin);
                            using (StreamReader streamReader = new StreamReader(stream, encoding, false, 4096, true))
                            {
                                foreach (var result in innerFileResults)
                                {
                                    // file info is known, set it now
                                    result.FileInfo = fileData;

                                    if (Utils.CancelSearch)
                                    {
                                        break;
                                    }

                                    result.SearchResults = Utils.GetLinesEx(streamReader, result.Matches, engine.LinesBefore, engine.LinesAfter);
                                }
                            }
                        }
                        else
                        {
                            foreach (var result in innerFileResults)
                            {
                                // file info is known, set it now
                                result.FileInfo = fileData;

                                if (Utils.CancelSearch)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        // short circuit this file
                        innerFileResults = null;
                    }
                    GrepEngineFactory.ReturnToPool(innerFileName, engine);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, string.Format(CultureInfo.CurrentCulture, "Failed to search inside archive '{0}'", innerFileName));
            }

            return(innerFileResults);
        }
예제 #24
0
        private static List <GrepSearchResult> Search(IGrepEngine engine, Stream input, string compositeFileName, string diskFile,
                                                      string[] intermediateFiles, string innerFileName, string searchPattern, SearchType searchType,
                                                      GrepSearchOption searchOptions, Encoding encoding)
        {
            List <GrepSearchResult> searchResults = new List <GrepSearchResult>();

            try
            {
                using (SevenZipExtractor extractor = new SevenZipExtractor(input))
                {
                    if (intermediateFiles.Length > 0)
                    {
                        int index = -1;
                        if (extractor.ArchiveFileData.Count == 1)
                        {
                            index = 0;
                        }
                        else
                        {
                            string name = intermediateFiles.First();
                            var    fd   = extractor.ArchiveFileData.FirstOrDefault(f => string.Equals(f.FileName, name));
                            if (fd != null)
                            {
                                index = fd.Index;
                            }
                        }
                        if (index > -1)
                        {
                            using (Stream stream = new MemoryStream())
                            {
                                extractor.ExtractFile(index, stream);
                                string[] newIntermediateFiles = intermediateFiles.Skip(1).ToArray();

                                searchResults.AddRange(
                                    Search(engine, stream, compositeFileName, diskFile, newIntermediateFiles, innerFileName,
                                           searchPattern, searchType, searchOptions, encoding));
                            }
                        }
                    }
                    else
                    {
                        int index = -1;
                        var info  = extractor.ArchiveFileData.FirstOrDefault(r => r.FileName == innerFileName);
                        if (info != null)
                        {
                            index = info.Index;
                        }
                        else if (extractor.ArchiveFileNames.Count == 1 && extractor.ArchiveFileNames[0] == "[no name]")
                        {
                            index = 0;
                        }

                        if (index > -1)
                        {
                            using (Stream stream = new MemoryStream())
                            {
                                extractor.ExtractFile(index, stream);
                                stream.Seek(0, SeekOrigin.Begin);

                                // Need to check the encoding of each file in the archive. If the encoding parameter is not default
                                // then it is the user-specified code page.  If the encoding parameter *is* the default,
                                // then it most likely not been set, so get the encoding of the extracted text file:
                                if (encoding == Encoding.Default && !Utils.IsBinary(stream))
                                {
                                    stream.Seek(0, SeekOrigin.Begin);
                                    encoding = Utils.GetFileEncoding(stream);
                                }

                                var innerFileResults = engine.Search(stream, innerFileName, searchPattern, searchType, searchOptions, encoding);

                                if (innerFileResults.Count > 0)
                                {
                                    using (Stream readStream = new MemoryStream())
                                    {
                                        extractor.ExtractFile(index, readStream);
                                        readStream.Seek(0, SeekOrigin.Begin);
                                        using (StreamReader streamReader = new StreamReader(readStream, encoding))
                                        {
                                            foreach (var result in innerFileResults)
                                            {
                                                if (Utils.CancelSearch)
                                                {
                                                    break;
                                                }

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

                foreach (GrepSearchResult result in searchResults)
                {
                    result.InnerFileName     = result.FileNameDisplayed;
                    result.FileNameDisplayed = compositeFileName;
                    result.FileNameReal      = diskFile;
                    result.ReadOnly          = true;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, string.Format("Failed to search inside archive '{0}'", diskFile));
            }
            return(searchResults);
        }