Есть ли способ получить MailMessages с сервера IMAP с помощью MailKit и сохранить их на диск? - PullRequest
0 голосов
/ 23 октября 2019

Мне нужно получить все электронные письма с сервера IMAP и сохранить все сообщения на жесткий диск. Я выбрал MailKit, чтобы выполнить ту же задачу. Условие - я должен получить электронные письма всех папок, такие как Контакты / Календарь / Черновик / Входящие / Отправленные / Синхронизация и т. Д., И, если доступно, то дочерние папки соответствующей папки. например,

|- Inbox
    |- Inbox/Child folder 1
    |- Inbox/Child folder 2
|- Sent
    |- Sent/Child folder 3
    .
    .
    .

и так далее. Я могу выбрать все папки, используя приведенный ниже код.

Код:

public List<string> GetAllFolders() =>
    client.GetFolder(client.PersonalNamespaces[0])
    .GetSubfolders(false)
    .Select(x => x.Name).ToList<string>();

Вывод:

Calendar
Contacts
Conversation History
Deleted Items
Drafts
INBOX
Journal
Junk Email
Notes
Outbox
RSS Feeds
Sent Items
Sync Issues
Tasks

Еще одно углубление вниз, чтобы получить соответствующую дочернюю папку

foreach (var folder in parentFolderList)
    subFolders.AddRange(client.GetFolders(new FolderNamespace('/', folder), false).Select(x => x.FullName).ToList());
public bool GetInboxFolderListNormalLoop(string filePath, List<string> personalFolderList)
{
    bool isSuccess = false;
    try
    {
        List<string> subFolders = new List<string>();
        personalFolderList.ForEach(x => subFolders.Add(x));

        if (personalFolderList.Count == 0)
            return false;

        foreach (var folder in personalFolderList)
            subFolders.AddRange(client.GetFolders(new FolderNamespace('/', folder), false).Select(x => x.FullName).ToList());

        if (subFolders.Count > 0)
            using (Stream str = new FileStream(filePath, FileMode.Create))
                SaveMailMessage(str as FileStream, subFolders);

        isSuccess = true;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error: {ex}");
        throw;
    }
    return isSuccess;
}

Наконец, чтобы сохранить сообщение на жесткий диск, я написал следующий код:

public void SaveMailMessage(FileStream str, List<string> subFoldersList)
{
    foreach (var sFolder in subFoldersList)
    {
        var subFolder = client.GetFolder(sFolder);

        if (!subFolder.IsOpen)
            subFolder.Open(FolderAccess.ReadOnly);

        Console.Write($"\n\t{sFolder} [{subFolder.Count} mails]: \t");

        IList<UniqueId> uniqueIds = subFolder.Search(MailKit.Search.SearchQuery.All);

        int cnt = uniqueIds.Count;
        int counter = 1;
        foreach (var uid in uniqueIds)
        {
            try
            {
                var msg = subFolder.GetMessage(uid);
                msg.WriteTo(MimeKit.FormatOptions.Default, str);
                drawTextProgressBar(counter, cnt);
            }
            catch (MessageNotFoundException mEx)
            {
                Console.WriteLine($"\n\tUnique Id: {uid}\n\tError: {mEx.Message}");
            }
            counter++;
        }
    }
}

Сохраняет файл в формате .eml / .msg. Но когда я пытаюсь открыть этот файл, в Outlook всегда отображается сообщение об ошибке «Файл используется другой программой или у вас нет прав доступа к этому файлу».

Я хочу получить все сообщения и сохранить файл вдиск, на котором я могу это сделать. Но не удалось открыть этот файл, который бесполезен.

Как это сделать? Примечание. Я использую свою собственную учетную запись электронной почты для целей тестирования.

Обновление: Добавлено GetInboxFolderListNormalLoop (строка filePath, List personalFolderList)

...