【问题标题】:Extracting/Scanning emails from Outlook using C#使用 C# 从 Outlook 中提取/扫描电子邮件
【发布时间】:2018-01-23 10:52:58
【问题描述】:

我正在尝试制作一个 Windows 窗体应用程序,它可以“隐藏”在任务栏中(如 WiFi 等),配备计时器,并且每 10 秒扫描一次 Outlook 中的电子邮件收件箱。

第一部分工作正常,但我无法让扫描工作。起初我只是想提取电子邮件主题的名称并将它们放入一个文本文件中,只是为了测试代码。但最后我想扫描一个特定的收件箱(我的 Outlook 上有几个,比如 5 或 6 个,关联了不同的邮件地址,我在互联网上找不到任何东西来定位其中一个)并制作收到特定电子邮件时的弹出窗口或其他内容。

无论如何,这是我到目前为止的代码:

    public static bool isRunning = false;

    public Form1()
    {
        InitializeComponent();

        System.Timers.Timer timer = new System.Timers.Timer(10000);
        timer.Elapsed += OnTimedEvent;
        timer.Enabled = true;
    }


    private void Hide_Click(object sender, EventArgs e)
    {
        this.Hide();
        notifyIcon1.Visible = true;
    }

    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
    {
        this.Show();
        notifyIcon1.Visible = false;
    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Outlook.Application app = null;
        Outlook.MAPIFolder inbox = null;
        Outlook._NameSpace ns = null;

        if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
        {
            try
            {
                app = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
                inbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
                ns = app.GetNamespace("MAPI");
                List<Outlook.MailItem> ReceivedEmail = new List<Outlook.MailItem>();
                List<string> titles = new List<string>();

                foreach (Outlook.MailItem mail in inbox.Items)
                {
                    ReceivedEmail.Add(mail);
                }

                foreach (Outlook.MailItem mail in ReceivedEmail)
                {
                    titles.Add(mail.Subject.ToString());
                }

                File.WriteAllLines("C://Users/A222946/Desktop/allMails.txt", titles);

            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        else
        {
            MessageBox.Show("Please, start outlook..");
        }

    }
}

我在运行时发现的错误如下:

操作不可用(HRESULT 异常:0x800401E3 (MK_E_UNAVAILABLE)

我尝试了使用和不使用管理员权限,同样的错误。

更新

所以经过一些更改后,它现在看起来像这样:

private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Outlook.Application app = new Outlook.Application();
        Outlook.MAPIFolder inbox = null;
        Outlook._NameSpace ns = null;
        Outlook.Items items = null;

        if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
        {
            try
            {
                app = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
                ns = app.GetNamespace("MAPI");
                inbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
                items = inbox.Items;
                List<Outlook.MailItem> ReceivedEmail = new List<Outlook.MailItem>();
                List<string> titles = new List<string>();

                foreach (Object obj in items)
                {
                    if (obj is Outlook.MailItem)
                    {
                        ReceivedEmail.Add((Outlook.MailItem)obj);
                    } 
                }

                foreach (Outlook.MailItem mail in ReceivedEmail)
                {
                    titles.Add(mail.Subject.ToString());
                }

                File.WriteAllLines("C://Users/A222946/Desktop/allMails.txt", titles);

            }
            catch (COMException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        else
        {
            MessageBox.Show("Please, start outlook..");
        }

    }

但我仍然有这个错误:

对象引用未设置为对象的实例

另外,你知道我可以如何定位一个特定的邮箱吗?示例:“abcdefg@blabla.com”

【问题讨论】:

  • 好的,我在没有管理员权限的情况下重新启动了 Visual Studio,并且不再出现此错误。但我得到一个“对象引用未设置为对象的实例”。
  • 哪个对象获得了空引用?
  • 它是收件箱。因为它取决于之后启动的“ns”。我改变了他们的位置,这个错误得到了处理。现在我明白了,当它进入第一个 froeach 时:无法将类型为“System.__ComObject”的 COM 对象转换为接口类型“Microsoft.Office.Interop.Outlook.MailItem”。此操作失败,因为 IID 为“{00063034-0000-0000-C000-000000000046}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE))

标签: c# visual-studio email outlook


【解决方案1】:

我认为 COM 组件不可访问。 COM组件被一些Windows组件(如MS Office)使用。您需要使用STAThreadAttribute。

[STAThread]
static void Main(string[] args)
{
    // etc..
}

我认为这应该可以解决问题。

【讨论】:

    【解决方案2】:

    首先,这确实需要一个 Outlook COM 插件(在 Outlook 运行时运行),而不是一个单独的 exe,用于检测 Outlook 何时运行。

    话虽如此,您正在使用Namespace.GetDefaultFolder。如果商店已在配置文件中打开,您需要使用的是 Store.GetDefaultFolder(其中 Store 是从 Namespace.Stores 集合中检索到的)。或者 Namespace.CreateRecipient / Namespace.GetSharedDefaultFolder 如果商店尚未在配置文件中打开。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 2015-07-09
      • 2011-12-17
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      相关资源
      最近更新 更多