Вопрос по c#, outlook-2010 – Можно только отправлять электронную почту через Outlook, если Outlook открыт

13

Я хочу использовать отправку электронной почты через Outlook, как описаноВот, Он работает нормально, пока я уже открыл Outlook. Так, например, если Outlook свернут, и я выполняю свой код, тогда я могу отправить письмо просто отлично. Но если Outlook закрыт, я получаю исключение:

{System.Runtime.InteropServices.COMException (0x80004004): Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))
   at Microsoft.Office.Interop.Outlook._MailItem.get_Recipients()
   at OutlookExample.Form1.btnSendEmail_Click(Object sender, EventArgs e) in C:\Users\abc\Documents\Visual Studio 2008\Projects\OutlookExample\OutlookExample\Form1.cs:line 28}

Вот код:

using Outlook = Microsoft.Office.Interop.Outlook;

...

private void btnSendEmail_Click(object sender, EventArgs e)
{
    try
    {
        Outlook.Application oApp = new Outlook.Application();
        Outlook.MailItem oMsg = Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
            oMsg.HTMLBody = "Hello, here is your message!";
            oMsg.Subject = "This is a test message";
            Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
            Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("[email protected]");
            oRecip.Resolve();
            oMsg.Send();
            oRecip = null;
            oRecips = null;
            oMsg = null;
            oApp = null;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

Почему это не работает?

Edit: Here is the solution

using Outlook = Microsoft.Office.Interop.Outlook;

...

private void btnSendEmail_Click(object sender, EventArgs e)
{
    try
    {
        Outlook.Application oApp = new Outlook.Application();

        // These 3 lines solved the problem
        Outlook.NameSpace ns = oApp.GetNamespace("MAPI");
        Outlook.MAPIFolder f = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
        System.Threading.Thread.Sleep(5000); // test

        Outlook.MailItem oMsg = Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
            oMsg.HTMLBody = "Hello, here is your message!";
            oMsg.Subject = "This is a test message";
            Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
            Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("[email protected]");
            oRecip.Resolve();
            oMsg.Send();
            oRecip = null;
            oRecips = null;
            oMsg = null;
            oApp = null;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}
SLaks, я хочу. К сожалению, я поддерживаю код VB6 и просто воспроизвел проблему в C #. Kasper Hansen
Не используйте Outlook. Вместо этого используйте System.Net.Mail. SLaks
Хороший вопрос. Вы уверены, что вы еще не вошли в систему? BugFinder

Ваш Ответ

2   ответа
12

Мне не понравилась идея использовать Thread.Sleep в течение 5 секунд, поэтому я нашел другое решение, которое сработало для меня:

Все, что вам нужно, это получить объект Inspector для вновь созданного

Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Inspector oInspector = oMsg.GetInspector;

Ответ был опубликован вГруппы Google изначально для Outlook 2007 (но у меня он работал с Outlook 2010)

Спасибо. Отличная работа :)
Из того, что я помню, это просто заставляет Outlook инициализировать. И я не проверяю это значение,
Итак, вы проверите, чтобы увидеть, если этоnull? Или это просто заставляет Outlook инициализироваться, если вы пытаетесь получить объект инспектора, а Outlook еще не запущен?
Как этот объект инспектора помогает, хотя? Он нигде не используется или я что-то упустил?
Оказалось, что Outlook возвращает Inspector только после того, как он правильно инициализирован. Это хитрость. Вы не должны его использовать.
13

Следующий код надежно работал на меня в течение нескольких месяцев:

            app = new Microsoft.Office.Interop.Outlook.Application();
            Microsoft.Office.Interop.Outlook.NameSpace ns = app.GetNamespace("MAPI");
            f = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
            Thread.Sleep(5000); // a bit of startup grace time.

Если Outlook был открыт, он использует его, если не его открыл. Конечно, если ваш внешний вид требует, чтобы вы вошли в систему, ваш код этого не допустит. Некоторые системы затрудняют автоматический вход в систему.

Это сработало, спасибо. Kasper Hansen

Похожие вопросы