目录使用后台工作程序进行搜索

时间:2016-02-01 14:53:52

标签: c# backgroundworker directorysearcher

在我的应用程序中,我可以选择搜索目录。如果用户搜索本地驱动器,那么我首先搜索目录(搜索索引),然后搜索目录

DirectoryInfo.GetDirectories("*" + AsearchString + "*",System.IO.SearchOption.AllDirectories)

在网络搜索(网络文件夹)的情况下,我只进行目录搜索。现在问题是,用户可能拥有或不拥有文件或文件夹的访问权限。我正在接收未经授权的异常,后台工作人员就在那里停止,我的困惑是如何捕获异常(如果PathTooLongunauthorized异常,这种情况发生在我搜索网络驱动器时)所以如果有只是记录或省略它并继续工作是一个例外。

我正在将我的工作放在下面,我不知道为什么try/catch无法工作,或者我应该移动它,以便在例外的情况下它会忽视并继续前进。我不得不在下面填写大量代码,为此道歉,我感谢任何建议。

更新: 忽略do work中的异常将停止bcw,所以我发现我的异常处理是不正确的。我已经更新了我的代码。

private void bwSearch_DoWork(object sender, DoWorkEventArgs e)
{
    if (e.Argument != null && e.Argument.GetType() == typeof(List<string>))
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new Action(() => this.Cursor = Cursors.WaitCursor));
        }
        else 
        {
            this.Cursor = Cursors.WaitCursor;
        }
        listViewBWSearchStatus = true;
        List<string> par = e.Argument as List<string>;
        string path = par[0];
        string searchString = par[1];

        try
        {
            if (FileSystemHelper.PathIsNetworkPath(path))
            {
                DirectoryInfo dInfo = new DirectoryInfo(path);
                foreach (FileInfo fi in dInfo.GetFiles("*" + searchString + "*.*", System.IO.SearchOption.AllDirectories))
                {
                    if (bwSearch.CancellationPending)
                    {
                        e.Cancel = true;
                        if (this.InvokeRequired)
                        {
                            this.BeginInvoke(new Action(() => this.Cursor = Cursors.Default));
                        }
                        else
                        {
                            this.Cursor = Cursors.Default;
                        }
                        break;
                    }
                    bwSearch.ReportProgress(0, fi);
                }
                foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories))
                {
                    if (bwSearch.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                    bwSearch.ReportProgress(0, d);
                }
            }
            else
            {
                var connection = new OleDbConnection(@"Provider=Search.CollatorDSO;Extended Properties=""Application=Windows""");
                string searchDirectoryFormated = path.Replace(@"\", @"/");

                // Folder name search (case insensitive), does not search sub directories
                var directorySearchQuery = @"SELECT System.ItemName,System.ItemPathDisplay FROM SystemIndex " +
                @"WHERE directory = 'file:" + searchDirectoryFormated + "' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%" + searchString + "%' ";

                // File name search (case insensitive), does not search sub directories
                var fileSearchQuery = @"SELECT System.ItemName,System.ItemPathDisplay FROM SystemIndex " +
                            @"WHERE directory = 'file:" + searchDirectoryFormated + "' AND System.ItemName LIKE '%" + searchString + "%' ";

                connection.Open();

                var command = new OleDbCommand(directorySearchQuery, connection);
                Dictionary<string, string> directoryResult = new Dictionary<string, string>();
                using (var r = command.ExecuteReader())
                {
                    while (r.Read())
                    {
                        if (bwSearch.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                        if (!directoryResult.ContainsKey(r.GetString(1)))
                        {
                            directoryResult.Add(r.GetString(1), r.GetString(0));
                            DirectoryInfo dirInfoIndexed = new DirectoryInfo(r.GetString(1));
                            bwSearch.ReportProgress(0, dirInfoIndexed);
                        }
                    }
                }

                command = new OleDbCommand(fileSearchQuery, connection);
                Dictionary<string, string> fileResult = new Dictionary<string, string>();
                using (var r = command.ExecuteReader())
                {
                    while (r.Read())
                    {
                        if (bwSearch.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                        if (!fileResult.ContainsKey(r.GetString(1)))
                        {
                            fileResult.Add(r.GetString(1), r.GetString(0));
                            FileInfo fileInfoIndexed = new FileInfo(r.GetString(1));
                            bwSearch.ReportProgress(0, fileInfoIndexed);
                        }
                    }
                }


                connection.Close();

                DirectoryInfo dInfo = new DirectoryInfo(path);

                foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories))
                {
                    if (bwSearch.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                    bwSearch.ReportProgress(0, d);
                }

                foreach (FileInfo fi in dInfo.GetFiles("*" + searchString + "*.*", System.IO.SearchOption.AllDirectories))
                {
                    if (bwSearch.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                    bwSearch.ReportProgress(0, fi);
                }
            }
        }
        //catch (UnauthorizedAccessException) { } // ignoring the exception will stop the background worker
        catch (UnauthorizedAccessException) { throw;}
        catch (System.Exception )
        {
            throw;// new Exception(ex.Message);
        }
    }
}

private void bwSearch_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (e.UserState != null && e.UserState.GetType() == typeof(FileInfo))
    {

        FileInfo fInfo = e.UserState as FileInfo;
        ListViewItem[] searchInfo = this.listView.Items.Find(Path.GetFileNameWithoutExtension(fInfo.Name), false);
        if (searchInfo == null || searchInfo.Count() == 0)
        {
            string fileFullName = fInfo.FullName;
            string lastAccessTime = fInfo.LastAccessTime.ToShortDateString();
            string imageKey = "";
            if (this.listView.SmallImageList.Images.ContainsKey(fInfo.Extension.ToLower()))
                imageKey = fInfo.Extension.ToLower();
            else
                imageKey = Explorer._Unknown;
            string strFileType = Explorer._Unknown;
            fileExtensionToFileType.TryGetValue(fInfo.Extension.ToString(), out strFileType);
            if (String.IsNullOrWhiteSpace(strFileType))
                strFileType = Explorer._Unknown;
            ListViewItem itemL = new ListViewItem(Path.GetFileNameWithoutExtension(fInfo.Name), imageKey);
            itemL.Name = fInfo.Name;
            itemL.Tag = fInfo;
            ListViewItem.ListViewSubItem[] subItem = new ListViewItem.ListViewSubItem[]
            {
                new ListViewItem.ListViewSubItem(itemL, lastAccessTime),
                new ListViewItem.ListViewSubItem(itemL, strFileType),
                new ListViewItem.ListViewSubItem(itemL, Explorer.SizeSuffix(fInfo.Length)),
                new ListViewItem.ListViewSubItem(itemL, fileFullName)
            };
            itemL.SubItems.AddRange(subItem);
            this.BeginInvoke(new MethodInvoker(delegate
            {
                this.listView.BeginUpdate();
                this.listView.Items.Add(itemL);
                this.listView.EndUpdate();
            }));
        }
    }
    else if (e.UserState != null && e.UserState.GetType() == typeof(DirectoryInfo))
    {

        DirectoryInfo dInfo = e.UserState as DirectoryInfo;
        string fullName = dInfo.FullName;
        ListViewItem[] searchDirectories = this.listView.Items.Find(dInfo.Name, false);
        if (searchDirectories == null || searchDirectories.Count() == 0)
        {
            ListViewItem itemL = new ListViewItem(dInfo.Name, Strings.FolderOpen);
            itemL.Name = dInfo.Name;
            itemL.Tag = dInfo;
            ListViewItem.ListViewSubItem[] subItem = new ListViewItem.ListViewSubItem[]
            {
                new ListViewItem.ListViewSubItem(itemL, dInfo.LastAccessTime.ToShortDateString()),
                new ListViewItem.ListViewSubItem(itemL, "File folder"),
                new ListViewItem.ListViewSubItem(itemL, ""),
                new ListViewItem.ListViewSubItem(itemL, fullName)
            };
            itemL.SubItems.AddRange(subItem);
            this.BeginInvoke(new MethodInvoker(delegate
            {
                this.listView.BeginUpdate();
                this.listView.Items.Add(itemL);
                this.listView.EndUpdate();
            }));
        }
    }
}

private void bwSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        if (e.Error.GetType() == typeof(UnauthorizedAccessException))
        {
        }
        if (e.Error.GetType() == typeof(Exception))
        { }
    }
    if (e.Error == null && e.Cancelled == false)
    {
        _ResetEventSearch.Set();
        listViewBWSearchStatus = false;
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new Action(() => this.Cursor = Cursors.Default));
        }
        else
        {
            this.Cursor = Cursors.Default;
        }
    }
}

更新

此部分代码根据用户定义的字符串搜索文件或文件夹。我不想停止用户线程,因为搜索将是一堆工作,所以我介绍了后台工作者。当我尝试读取foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories))中的目录时,我遇到了异常。我认为,当它试图获取目录信息或文件信息时,由于用户没有访问权限,它会被卡住。

最初我没有抛出异常,因此,在获得异常后,bcw没有进一步移动。相反,它报告了错误并提出了运行工人完成事件。在我添加throw之后,bcw继续为其余目录工作。

0 个答案:

没有答案