Я преобразую старый макрос Outlook VBA, который я создал, в надстройку C # VSTO.Этот инструмент предназначен для массового архивирования электронных писем в различные общие папки и локальный файл PST и должен иметь возможность находить электронные письма на основе критериев поиска пользователя.У меня было огромное количество времени для получения события AdvancedSearchComplete
для запуска в VBA, но в конце концов оно заработало.Конечно, теперь у меня такая же проблема в надстройке C # VSTO.
Чтобы использовать инструмент, пользователь вводит свои критерии в пользовательской форме, а затем нажимает Найти электронные письма кнопка, чтобы выполнить поиск с результатами, заполняющими представление данных.
public partial class Email_Archiver : Form
{
public Email_Archiver()
{
InitializeComponent();
//Add event handlers
Globals.ThisAddIn.Application.AdvancedSearchComplete += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_AdvancedSearchCompleteEventHandler(Application_AdvancedSearchComplete);
}
public void Application_AdvancedSearchComplete(Microsoft.Office.Interop.Outlook.Search SearchObject)
{ //Handles AdvancedSearchComplete event
if (SearchObject.Tag == "Archiver Search")
{
OutlookFunctions.SearchComplete = true;
MessageBox.Show(this, "Search Complete!","Email Search Error",MessageBoxButtons.OK);
}
}
private void Find_Button_Click(object sender, EventArgs e)
{
//Set datagridview datasource
EmailList.DataSource = FindEmails();
EmailList.Columns["EntryID"].Visible = false;
}
public DataTable FindEmails()
{
var dt = new DataTable();
//Format DataTable
dt.Columns.Add("EntryID", typeof(string));
dt.Columns.Add("Project No.", typeof(int));
dt.Columns.Add("Subject", typeof(string));
dt.Columns.Add("Sender", typeof(string));
dt.Columns.Add("Recipient", typeof(string));
dt.Columns.Add("Time Sent", typeof(DateTime));
dt.Columns.Add("Size", typeof(decimal));
//Do stuff to get "searchFolders" and "searchCriteria" from form
//...
dt = OutlookFunctions.RunAdvancedSearch(searchFolders, searchCriteria);
return dt;
}
}
class OutlookFunctions
{
public static bool SearchComplete;
public static DataTable RunAdvancedSearch(string[] searchFolders, string[] searchCriteria)
{
//Get Outlook namespace
var oApp = Globals.ThisAddIn.Application;
var oNS = oApp.GetNamespace("mapi");
Microsoft.Office.Interop.Outlook.Search advSearch = null;
//Do other stuff to properly set up the scope and filter
//...
//Perform search
SearchComplete = false;
try
{
advSearch = oApp.AdvancedSearch(scope, filter, false, "Archiver Search");
}
catch (System.Exception ex)
{
MessageBox.Show("An error has occurred during the search for emails. \n \n"
+ ex.Message);
return null;
}
Stopwatch timer = new Stopwatch();
timer.Start();
while (!SearchComplete && timer.Elapsed.TotalSeconds < 10)
{
//Do nothing
}
if (!SearchComplete)
{
advSearch.Stop();
}
if (advSearch != null)
{
var resultTable = new DataTable();
//Send results to resultTable
return resultTable;
}
return null;
}
}
Поиск работает, и я получаю правильные результаты, но мне пришлось добавить в таймер, чтобы все пошло дальше, иначе код никогда не завершитсяпотому что AdvancedSearchComplete
не срабатывает.Я по-прежнему получаю все электронные письма, которые я ищу, и выполняю по существу один и тот же поиск только в проводнике Outlook, я получаю те же результаты за доли секунды.
После того, как таймер завершит поиск иdatagridview заполнен результатами, ТОГДА AdvancedSearchComplete
срабатывает, и я получаю "Поиск завершен!"сообщение.
Что мне здесь не хватает, что мешает событию инициировать поиск (своевременно)?