【问题标题】:C# COM Exception when creating Outlook 2007 Application instance (80010001, ErrorCode -2147418111)创建 Outlook 2007 应用程序实例时出现 C# COM 异常(80010001,错误代码 -2147418111)
【发布时间】:2015-08-07 09:38:12
【问题描述】:

我创建了一个 Winforms 应用程序来安排一些 Crystal Reports 的执行。此应用程序计划使用标准的 Windows XP 计划任务功能在我的 Windows 域用户下执行。

我添加了让我的应用程序在报告执行期间发生故障时发送电子邮件的功能,并且在当天所有计划的报告都执行后发送完成电子邮件。

以下代码显示了我将如何创建 Microsoft.Office.Interop.Outlook.Application 实例的测试,然后创建 _MailItem 用于填充和发送:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace MailTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Boolean eResult = false;
            String emailError = "";

            eResult = sendEmail("blah@blah.com", "Email Testing", "This is a test", false, out emailError);

            if (eResult)
                MessageBox.Show("Email sent!");
            else
                MessageBox.Show("Email failed->" + emailError);
        }

        public static Boolean sendEmail(String recipients, String subject, String body, Boolean highImportance, out String error)
        {
            Boolean success = true;
            error = "";

            Outlook.Application outApp = null;

            // Create an instance of the Outlook Application.
            try
            {
                outApp = new Outlook.Application();
            }
            catch (System.Runtime.InteropServices.COMException ce)
            {
                // We're going to do nothing with this at this time, as something weird happens if Outlook is not
                // open when outApp is created above, and a COM exception is raised - however, Outlook ends up
                // being opened, and creating an Application instance again succeeds. This is a workaround until I can
                // find more detail on the COM exception.
                MessageBox.Show(ce.Message);
            }
            catch (System.Exception e)
            {
                // Any other type of Exception should be reported back to the caller with a failure status.
                error = e.Message;
                return false;
            }

            // Re-try the setting of outApp in case the original attempt failed above.
            if (outApp == null)
            {
                try
                {
                    outApp = new Outlook.Application();
                }
                catch (Exception e)
                {
                    // If we fail to successfully open Outlook the second time, a different error has occurred, so
                    // we just want to return the exception message with false as result.
                    error = e.Message;
                    return false;
                }
            }

            // Now create an Outlook mail item to populate and send.
            Outlook.MailItem msg = outApp.CreateItem(Outlook.OlItemType.olMailItem);
            // etc etc

当第一次尝试创建新的 Outlook 应用程序时,Outlook 尚未在我的 PC 上运行,Outlook 已打开(我看到它的图标出现在系统托盘中),但在该行中引发了以下异常

outApp = new Outlook.Application();

异常详情:

System.Runtime.InteropServices.COMException was unhandled
  Message=Creating an instance of the COM component with CLSID {0006F03A-0000-0000-C000-000000000046} from the IClassFactory failed due to the following error: 80010001.
  Source=mscorlib
  ErrorCode=-2147418111
  StackTrace:
       at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType)
       at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType)
       at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj)
       at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
       at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
       at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
       at System.Activator.CreateInstance(Type type, Boolean nonPublic)
       at System.Activator.CreateInstance(Type type)
       at MailTest.Form1.sendEmail(String recipients, String subject, String body, Boolean highImportance, String& error) in c:\Documents and Settings\CT100751\My Documents\Visual Studio 2010\Projects\MailTest\MailTest\Form1.cs:line 43
       at MailTest.Form1.button1_Click(Object sender, EventArgs e) in c:\Documents and Settings\CT100751\My Documents\Visual Studio 2010\Projects\MailTest\MailTest\Form1.cs:line 25
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at MailTest.Program.Main() in c:\Documents and Settings\CT100751\My Documents\Visual Studio 2010\Projects\MailTest\MailTest\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

我在网上搜索了错误80010001和ErrorCode -2147418111的组合,一无所获。

但是,由于 Outlook 现在已打开,如果我再次尝试创建应用程序实例,我会成功,然后可以成功发送电子邮件。

我对这个变通办法不满意,并且希望了解 COM 异常的原因,看看我是否可以解决它。

请注意,这是内部公司电子邮件,因此我无法访问 SMTP 服务器,因此我必须使用 Outlook 进行发送。

有人知道这里发生了什么吗?

【问题讨论】:

    标签: winforms c#-4.0 com office-interop outlook-2007


    【解决方案1】:

    0x80010001 错误代码对应于 RPC_E_CALL_REJECTED。查看How to: Fix 'Application is Busy' and 'Call was Rejected By Callee' Errors 文章,该文章描述了类似问题并提供了避免此类问题的示例代码。

    此外,Microsoft 目前不推荐也不支持任何无人值守、非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM 和 NT 服务)的 Microsoft Office 应用程序自动化,因为 Office 可能会出现在此环境中运行 Office 时行为不稳定和/或死锁。

    如果您要构建在服务器端上下文中运行的解决方案,您应该尝试使用已确保无人值守执行安全的组件。或者,您应该尝试找到允许至少部分代码在客户端运行的替代方案。如果您使用服务器端解决方案中的 Office 应用程序,该应用程序将缺少许多成功运行所需的功能。此外,您将在整体解决方案的稳定性方面承担风险。

    Considerations for server-side Automation of Office 文章中了解更多信息。

    【讨论】:

    • 我已经查看了该 MSDN 文章,但看不到它如何应用于我的场景,因为我没有以编程方式从外部多线程应用程序调用 Visual Studio 自动化 - 或者我我错过了什么?我之前也看过您的最后两段,但再次认为这不适用,因为所有代码都是客户端的 - 此解决方案没有服务器端方面。
    • 我的应用程序实际上是一个交互式客户端应用程序,但如果配置为在应用程序启动时自动执行所需的报告,它可以在没有用户与之交互的情况下运行。
    猜你喜欢
    • 1970-01-01
    • 2011-01-21
    • 2011-01-31
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多