【问题标题】:Can only send email via Outlook if Outlook is open如果 Outlook 打开,则只能通过 Outlook 发送电子邮件
【发布时间】:2012-07-05 00:25:23
【问题描述】:

我想按照here 的描述使用通过 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("rhr@sonlinc.dk");
            oRecip.Resolve();
            oMsg.Send();
            oRecip = null;
            oRecips = null;
            oMsg = null;
            oApp = null;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

为什么这不起作用?

编辑:这是解决方案

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("rhr@sonlinc.dk");
            oRecip.Resolve();
            oMsg.Send();
            oRecip = null;
            oRecips = null;
            oMsg = null;
            oApp = null;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

【问题讨论】:

  • 不要使用 Outlook。相反,请使用 System.Net.Mail。
  • 好问题。确定它还没有登录吗?
  • SLaks,我希望。不幸的是,我正在维护 VB6 代码,只是在 C# 中复制了这个问题。

标签: c# outlook-2010


【解决方案1】:

我不喜欢使用 Thread.Sleep 5 秒的想法,所以我找到了另一个对我有用的解决方案:

您只需要获取新创建的 MailItem 的 Inspector 对象

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

答案是在 Google groups 中发布的,最初用于 Outlook 2007(但它适用于 Outlook 2010)

【讨论】:

  • 这个检查器对象有什么帮助呢?它没有在任何地方使用,或者我错过了什么?
  • 看来 Outlook 只有在正确初始化后才会返回 Inspector。这就是诀窍。你不必使用它。
  • 那么,你检查一下是不是null?或者,如果您尝试获取检查器对象并且 Outlook 尚未启动,它是否只是强制 Outlook 初始化?
  • 据我记忆,它只是强制 Outlook 初始化。而且我不会检查它的价值,
【解决方案2】:

以下代码对我来说已经可靠地工作了几个月:

            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 已打开,则使用它,如果未打开,则使用它。当然,如果您的 Outlook 要求您登录,您的代码将不允许这样做。有些系统让您难以自动登录。

【讨论】:

    猜你喜欢
    • 2016-12-01
    • 1970-01-01
    • 2011-09-14
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多