C# 通过Windows服务运行时操作不可用(HRESULT:0x800401E3(MK_E_不可用)的异常)?

C# 通过Windows服务运行时操作不可用(HRESULT:0x800401E3(MK_E_不可用)的异常)?,c#,.net,outlook,windows-services,ms-office,C#,.net,Outlook,Windows Services,Ms Office,我正试图从windows服务连接到outlook应用程序,但获取的异常操作不可用(来自HRESULT的异常:0x800401E3(MK_E_不可用)),这是我的代码 public void ItemSendEvent() { try { if (Process.GetProcessesByName(ApplicationConstants.OUTLOOK_PROCESS_NAME).Count() > 0)

我正试图从windows服务连接到outlook应用程序,但获取的异常操作不可用(来自HRESULT的异常:0x800401E3(MK_E_不可用)),这是我的代码

   public void ItemSendEvent()
    {
        try
        {
           if (Process.GetProcessesByName(ApplicationConstants.OUTLOOK_PROCESS_NAME).Count() > 0)
                {
                    // If so, use the GetActiveObject method to obtain the process and cast it to an Application object.
                    outlookApplication = Marshal.GetActiveObject(ApplicationConstants.OUTLOOK_APPLICATION_NAME) as Microsoft.Office.Interop.Outlook.Application;
                    Microsoft.Office.Interop.Outlook.NameSpace nameSpace = outlookApplication.GetNamespace(ApplicationConstants.OUTLOOK_NAME_SPACE);
                    nameSpace.Logon("", "", Missing.Value, Missing.Value);
                    nameSpace = null;
                    outlookApplication.ItemSend += outlookApplication_ItemSend;
                }
                log.Info("Outlook Item Send event registered successfully.");
        }
        catch (System.Exception ex)
        {
            log.Error("Exception occurred while registering Outlook Item Send event. " + ex.Message);
        }
    }

但当我通过Windows窗体应用程序启动它时,同样的代码工作正常。我浏览了一些网站,他们说outlook对象不在ROT表中。解决方案是什么。

两个常见问题可能导致这种情况

第一种情况是,您正在管理员模式下运行VisualStudio,并且您正在从VS中启动程序,而Office应用程序不是。要解决这个问题,您还需要在管理员模式下以提升的权限运行Office应用程序


第二个问题可能是由于调用
封送处理时应用程序未完全启动/加载。GetActiveObject(…)
Outlook或任何其他Office应用程序无法在Windows服务中运行,即使您的服务是以交互用户的身份运行。服务中只能使用扩展MAPI(仅限C++或Delphi)或类似扩展MAPI包装器(其族对象)


在您的特定情况下,您似乎试图捕获
应用程序.ItemSend
事件。绝对没有理由为此创建Windows服务。创建COM加载项-只要Outlook本身在同一安全上下文中的同一进程中运行,它就会被Outlook加载并运行。

您不需要将应用程序作为服务在后台运行


如果您的winform运行良好,只需将winform放在后台运行在systray上即可,例如

旧的但仍然重要的线程

在尝试使用访问Outlook数据时,我遇到了此错误

Try/Catch块中处理错误并提供更新Outlook选项可以解决问题:

const int ERROR_HRESULT_0x800401E3_MK_E_UNAVAILABLE= -2147221021;
        Outlook.Application application = null;
        // Check whether there is an Outlook process running.
        if (Process.GetProcessesByName("OUTLOOK").Any())
        {
            try
            {
                // If so, use the GetActiveObject method to obtain the process and cast it to an Application object.
                application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
                }
            }
            catch (Exception ex)
            {
                //This is the branch where you can get correctly the current Outlook instance
                if (ex.HResult == ERROR_HRESULT_0x800401E3_MK_E_UNAVAILABLE)
                {
                    application = new Outlook.Application();
                }
            }
        }
        else
        {
            application = new Outlook.Application();
        }
尽管newing技巧起作用,但不会创建其他Outlook实例


我只在安装了Office 365 64位的情况下对其进行了测试。

hello dmitry我创建了一个winforms应用程序,该应用程序工作正常,能够获取item send事件并获取所有详细信息,但我希望它作为服务在后台运行,并以静默方式捕获所有详细信息。:)再次,由于安全上下文不同,您将无法访问。您确实需要编写一个COM加载项(dll),它将由Outlook加载到proc中。@DmitryStreblechenko因此,请澄清一下-如果我们使用Redemption或Extended MPI,我们可以从另一个用户进程(不一定是服务)访问Outlook吗?您将无法访问Outlook或封送Namespace.MAPIOBJECT(即IMAPISession)如果安全上下文不同,则可以从outlook.exe地址空间,但您可以在proc中加载MAPI系统(因为它是一组DLL),并使用相同的配置文件创建自己的MAPI会话。现在,如果该配置文件使用缓存模式,共享该配置文件中的OST或PST文件可能会有问题,但您始终可以动态创建自己的临时配置文件以访问特定的Exchange邮箱(或在赎回时使用RDOSession.LogonHostedExchangeMailbox)。不幸的是,这不正确,但Dmitry的答案是肯定的,当我在VS中更改模式时(不是作为管理员),我没有得到异常