我尝试从Windows服务挂钩到Outlook应用程序,但出现异常 操作不可用(HRESULT的异常:0x800401E3(MK_E_UNAVAILABLE))这是我的代码。
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 表中。 解决方案是什么。
Outlook 或任何其他 Office 应用无法在 Windows 服务中运行,即使你的服务以交互式用户身份运行也是如此。只有扩展 MAPI(仅限 C++ 或 Delphi)或扩展 MAPI 包装器(如 Redemption)(我是它的作者 - 它的 RDO 系列对象)才能在服务中使用。
在您的特定情况下,您似乎正在尝试捕获Application.ItemSend
事件。绝对没有理由为此创建Windows服务。创建一个 COM 加载项 - 只要 Outlook 本身在同一安全上下文中的同一进程中运行,它就会由 Outlook 加载并运行。
两个常见问题可能会导致此问题。
第一种情况是,您在管理员模式下运行Visual Studio,并且从VS中启动程序,而Office应用程序则不是。若要解决此问题,还需要在管理员模式下使用提升的权限运行 Office 应用程序。
第二个可能是由于调用 Marshal.GetActiveObject(...)
时应用程序未完全启动/加载。
旧,但仍然很重要。
尝试使用 MS 示例访问 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实例,因为Outlook的行为类似于Singleton。
我只在安装了Office 365 64位的情况下对其进行了测试。
你不需要将你的应用程序作为一个服务来让它在后台......
如果您的 winform 运行良好,只需将您的 winform 放在后台运行在系统托盘上