次のコードを使用して、ユーザーから送信されたすべての電子メールを検索していますが、これはメインの受信トレイフォルダーのみを検索し、サブフォルダーはチェックしません。サブフォルダを含むすべてのメールアイテムを検索したいと思います。
WellKnownFolderName.Root
とWellKnownFolderName.Inbox
を試しましたが、これらはこれらのフォルダーのみを検索し、サブフォルダーは検索しません。
private static void SearchItems(string email)
{
ItemView iv = new ItemView(10);
FindItemsResults<Item> fiitems = _service.FindItems(WellKnownFolderName.Inbox, "from:[email protected]", iv);
foreach (Item item in fiitems)
{
Console.WriteLine("Subject:\t" + item.Subject);
Console.WriteLine("Received At:\t\t" + item.DateTimeReceived.ToString("dd MMMM yyyy"));
Console.WriteLine();
}
Console.WriteLine("Press Enter to continue");
Console.ReadLine();
}
Exchange内のAllItems
フォルダーでいくつかの情報を見つけました Glenのブログで 。以下に示すように、PowerShellスクリプトをC#に移植しました。
private static void SearchItems()
{
ExtendedPropertyDefinition allFoldersType =
new ExtendedPropertyDefinition(13825, MapiPropertyType.Integer);
FolderId rootFolderId = new FolderId(WellKnownFolderName.Root);
FolderView folderView = new FolderView(1000);
folderView.Traversal = FolderTraversal.Shallow;
SearchFilter searchFilter1 = new SearchFilter.IsEqualTo(allFoldersType, "2");
SearchFilter searchFilter2 = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "allitems");
SearchFilter.SearchFilterCollection searchFilterCollection =
new SearchFilter.SearchFilterCollection(LogicalOperator.And);
searchFilterCollection.Add(searchFilter1);
searchFilterCollection.Add(searchFilter2);
FindFoldersResults findFoldersResults =
_service.FindFolders(rootFolderId, searchFilterCollection, folderView);
if (findFoldersResults.Folders.Count > 0)
{
Folder allItemsFolder = findFoldersResults.Folders[0];
Console.WriteLine("Folder:\t" + allItemsFolder.DisplayName);
ItemView iv = new ItemView(1000);
FindItemsResults<Item> findResults =
allItemsFolder.FindItems("System.Message.DateReceived:01/01/2011..01/31/2011", iv);
foreach (Item item in findResults)
{
Console.WriteLine("Subject:\t" + item.Subject);
Console.WriteLine("Received At:\t\t" + item.DateTimeReceived.ToString("dd MMMM yyyy"));
Console.WriteLine("Is New:\t\t" + item.IsNew.ToString());
Console.WriteLine("Has Attachments:\t\t" + item.HasAttachments.ToString());
Console.WriteLine();
}
}
Console.WriteLine("Press Enter to continue");
Console.ReadLine();
}
サーバー上のすべてのフォルダーとサブフォルダーのコレクションだけが必要な場合は、リクエストをページングして、数回の呼び出しでサーバーからフォルダー階層全体を取得できます。重要なのはFolderView.Traversal
プロパティ。
たとえば、最大1,300個のフォルダを持つExchangeメールボックスの場合、以下のコードは2つの要求のみを行います。サーバーの制限以下である限り、ページサイズを好きなように設定できます。
参考:Exchange Online(Office365)の上限は、応答で最大1,000アイテムです。私はテストを行っていないため、オンプレミスのExchangeServerにクエリを実行するときに同様の制限について話すことはできません。
Imports Exchange = Microsoft.Exchange.WebServices.Data
Friend Module Main
Public Sub Main()
Dim oService As Exchange.ExchangeService
Dim oUsers As Dictionary(Of String, User)
oUsers = New Dictionary(Of String, User)
oUsers.Add("User1", New User("[email protected]", "Some-Fancy-Password1"))
oUsers.Add("User2", New User("[email protected]", "Some-Fancy-Password2"))
oUsers.ToList.ForEach(Sub(Credential As KeyValuePair(Of String, User))
File.Delete(LOG_FILE_PATH.ToFormat(Credential.Key))
End Sub)
oUsers.ToList.ForEach(Sub(Credential As KeyValuePair(Of String, User))
LogFileName = Credential.Key
Console.WriteLine("Getting message counts for mailbox [{0}]...", LogFileName)
Console.WriteLine()
oService = Service.ConnectToService(Credential.Value)
GetAllFolders(oService, LOG_FILE_PATH.ToFormat(Credential.Key))
Console.Clear()
End Sub)
Console.WriteLine()
Console.Write("Press any key to exit...")
Console.ReadKey()
End Sub
Private Sub GetAllFolders(Service As Exchange.ExchangeService, LogFilePath As String)
Dim oIsHidden As Exchange.ExtendedPropertyDefinition
Dim oFolders As List(Of Exchange.Folder)
Dim oResults As Exchange.FindFoldersResults
Dim lHasMore As Boolean
Dim oChild As Exchange.Folder
Dim oView As Exchange.FolderView
Dim _
nPageSize,
nOffSet As Short
Dim _
oPaths,
oPath As List(Of String)
oIsHidden = New Exchange.ExtendedPropertyDefinition(&H10F4, Exchange.MapiPropertyType.Boolean)
nPageSize = 1000
oFolders = New List(Of Exchange.Folder)
lHasMore = True
nOffSet = 0
Do While lHasMore
oView = New Exchange.FolderView(nPageSize, nOffSet, Exchange.OffsetBasePoint.Beginning)
oView.PropertySet = New Exchange.PropertySet(Exchange.BasePropertySet.IdOnly)
oView.PropertySet.Add(oIsHidden)
oView.PropertySet.Add(Exchange.FolderSchema.ParentFolderId)
oView.PropertySet.Add(Exchange.FolderSchema.DisplayName)
oView.PropertySet.Add(Exchange.FolderSchema.FolderClass)
oView.PropertySet.Add(Exchange.FolderSchema.TotalCount)
oView.Traversal = Exchange.FolderTraversal.Deep
oResults = Service.FindFolders(Exchange.WellKnownFolderName.MsgFolderRoot, oView)
oFolders.AddRange(oResults.Folders)
lHasMore = oResults.MoreAvailable
If lHasMore Then
nOffSet += nPageSize
End If
Loop
oFolders.RemoveAll(Function(Folder) Folder.ExtendedProperties(0).Value = True)
oFolders.RemoveAll(Function(Folder) Folder.FolderClass <> "IPF.Note")
oPaths = New List(Of String)
oFolders.ForEach(Sub(Folder)
oChild = Folder
oPath = New List(Of String)
Do
oPath.Add(oChild.DisplayName)
oChild = oFolders.SingleOrDefault(Function(Parent) Parent.Id.UniqueId = oChild.ParentFolderId.UniqueId)
Loop While oChild IsNot Nothing
oPath.Reverse()
oPaths.Add("{0}{1}{2}".ToFormat(Join(oPath.ToArray, DELIMITER), vbTab, Folder.TotalCount))
End Sub)
oPaths.RemoveAll(Function(Path) Path.StartsWith("Sync Issues"))
File.WriteAllText(LogFilePath, Join(oPaths.ToArray, vbCrLf))
End Sub
Private LogFileName As String
Private Const LOG_FILE_PATH As String = "D:\Emails\Remote{0}.txt"
Private Const DELIMITER As String = "\"
End Module
Friend Class Service
Public Shared Function ConnectToService(User As User) As Exchange.ExchangeService
Return Service.ConnectToService(User, Nothing)
End Function
Public Shared Function ConnectToService(User As User, Listener As Exchange.ITraceListener) As Exchange.ExchangeService
Dim oService As Exchange.ExchangeService
oService = New Exchange.ExchangeService(Exchange.ExchangeVersion.Exchange2013_SP1)
oService.Credentials = New NetworkCredential(User.EmailAddress, User.Password)
oService.AutodiscoverUrl(User.EmailAddress, AddressOf RedirectionUrlValidationCallback)
If Listener IsNot Nothing Then
oService.TraceListener = Listener
oService.TraceEnabled = True
oService.TraceFlags = Exchange.TraceFlags.All
End If
Return oService
End Function
Private Shared Function RedirectionUrlValidationCallback(RedirectionUrl As String) As Boolean
With New Uri(RedirectionUrl)
Return .Scheme.ToLower = "https"
End With
End Function
End Class
Friend Class User
Public Sub New(EmailAddress As String)
_EmailAddress = EmailAddress
_Password = New SecureString
End Sub
Public Sub New(EmailAddress As String, Password As String)
_EmailAddress = EmailAddress
_Password = New SecureString
Password.ToList.ForEach(Sub(Chr As Char)
Me.Password.AppendChar(Chr)
End Sub)
Password.MakeReadOnly()
End Sub
Public Shared Function GetUser() As User
Dim sEmailAddress As String
Dim oUserInput As ConsoleKeyInfo
Console.Write("Enter email address: ")
sEmailAddress = Console.ReadLine
Console.Write("Enter password: ")
GetUser = New User(sEmailAddress)
While True
oUserInput = Console.ReadKey(True)
If oUserInput.Key = ConsoleKey.Enter Then
Exit While
ElseIf oUserInput.Key = ConsoleKey.Escape Then
GetUser.Password.Clear()
ElseIf oUserInput.Key = ConsoleKey.Backspace Then
If GetUser.Password.Length <> 0 Then
GetUser.Password.RemoveAt(GetUser.Password.Length - 1)
End If
Else
GetUser.Password.AppendChar(oUserInput.KeyChar)
Console.Write("*")
End If
End While
If GetUser.Password.Length = 0 Then
GetUser = Nothing
Else
GetUser.Password.MakeReadOnly()
Console.WriteLine()
End If
End Function
Public ReadOnly Property EmailAddress As String
Public ReadOnly Property Password As SecureString
End Class
Friend Class TraceListener
Implements Exchange.ITraceListener
Public Sub Trace(TraceType As String, TraceMessage As String) Implements Exchange.ITraceListener.Trace
File.AppendAllText("{0}.txt".ToFormat(Path.Combine("D:\Emails\TraceOutput", Guid.NewGuid.ToString("D"))), TraceMessage)
End Sub
End Class