Если в Outlook приходит почта, запустите другой метод (Outlook зависает) Interlop.Outlook C# WPF - PullRequest
0 голосов
/ 30 мая 2020

У меня есть следующая часть метода в приложении WPF:

// This method check Emails
public void CheckForEmails()
{
    Outlook.Application application = null;
    Outlook.NameSpace nameSpace = null;

    if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
    {
        application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
    }
    else
    {
        application = new Outlook.Application();
        nameSpace = application.GetNamespace("MAPI");
        nameSpace.Logon("", "", Missing.Value, Missing.Value);
    }

    nameSpace = application.GetNamespace("MAPI");
    Outlook.MAPIFolder inbox = nameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
    //nameSpace.SendAndReceive(true);

    var items = inbox.Items;
    items.ItemAdd += AnyMethod;
}

//This method execute any method
public void AnyMethod(object Item)
{
    MessageBox.Show("GOOD!");
}

//This is the is the xaml.cs view which initialize the emailAction class if the window is open
public partial class PageView : UserControl
{
    public DownloadDeviceView()
    {
        InitializeComponent();
        DataContext = new DownloadDeviceViewModel();
        EmailAction emailAction = new EmailAction();
    }
}

Этот метод должен выполнять метод AnyMethod() при получении нового электронного письма в Outlook.

проблема, как ни странно, всегда другая: иногда все работает. Иногда метод вообще не работает. А иногда Outlook зависает и снова ничего не происходит.

1 Ответ

1 голос
/ 30 мая 2020

Вы должны определить исходный объект в глобальной области видимости (на уровне класса), чтобы событие запускалось и оставалось живым объект, т. Е. Предотвращая его смахивание сборщиком мусора. Например:

Outlook.Items = null;
Outlook.Application application = null;
    Outlook.NameSpace nameSpace = null;

public void CheckForEmails()
{


    if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
    {
        application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
    }
    else
    {
        application = new Outlook.Application();
        nameSpace = application.GetNamespace("MAPI");
        nameSpace.Logon("", "", Missing.Value, Missing.Value);
    }

    nameSpace = application.GetNamespace("MAPI");
    Outlook.MAPIFolder inbox = nameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
    //nameSpace.SendAndReceive(true);

    items = inbox.Items;
    items.ItemAdd += AnyMethod;
}

Событие ItemAdd не запускается, если вы получаете одновременно много элементов (более шестнадцати). Это известное ограничение объектной модели Outlook, существующее десятилетиями.

Я бы рекомендовал вместо этого использовать событие NewMailEx класса Application. Это событие запускается один раз для каждого полученного элемента, который обрабатывается Microsoft Outlook. Элемент может быть одного из нескольких различных типов, например, MailItem, MeetingItem или SharingItem. Строка EntryIDsCollection содержит идентификатор записи, соответствующий этому элементу.

Событие NewMailEx запускается, когда новое сообщение поступает в папку «Входящие» и до того, как выполняется обработка правил клиента. Вы можете использовать идентификатор записи, возвращенный в массиве EntryIDCollection, для вызова метода NameSpace.GetItemFromID и обработки элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...