在我的应用程序中,我可以选择搜索目录。如果用户搜索本地驱动器,那么我首先搜索目录(搜索索引),然后搜索目录
DirectoryInfo.GetDirectories("*" + AsearchString + "*",System.IO.SearchOption.AllDirectories)
。
在网络搜索(网络文件夹)的情况下,我只进行目录搜索。现在问题是,用户可能拥有或不拥有文件或文件夹的访问权限。我正在接收未经授权的异常,后台工作人员就在那里停止,我的困惑是如何捕获异常(如果PathTooLong
或unauthorized
异常,这种情况发生在我搜索网络驱动器时)所以如果有只是记录或省略它并继续工作是一个例外。
我正在将我的工作放在下面,我不知道为什么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继续为其余目录工作。