我尝试从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 Form Application启动它时它的工作正常。我经历了一些网站,他们说Outlook对象不在ROT表中。什么是解决方案。
答案 0 :(得分:4)
即使您的服务作为交互式用户运行,Outlook或任何其他Office应用也无法在Windows服务中运行。只能在服务中使用扩展MAPI(仅限C ++或Delphi)或扩展MAPI包装,如Redemption(其RDO系列对象)。
在您的特定情况下,您似乎试图捕获Application.ItemSend
事件。绝对没有理由为此创建Windows服务。创建一个COM插件 - 只要Outlook本身在同一安全上下文中的同一进程中运行,它就会被Outlook加载并运行。
答案 1 :(得分:2)
两个常见问题可能导致这种情况。
第一个是您在管理员模式下运行Visual Studio,而您是从VS中启动程序,而Office应用程序则不是。要解决此问题,您还需要在管理员模式下以提升的权限运行Office应用程序。
第二种情况可能是由于您致电Marshal.GetActiveObject(...)
时应用程序未完全启动/加载。
答案 2 :(得分:0)
您不需要将您的应用程序作为服务来获取它的背景......
如果你的winform运行良好,只需将你的winform放在系统托盘上的后台运行
答案 3 :(得分:0)
旧但仍然重要的线程。
我遇到这种错误,尝试使用MS example访问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();
}
尽管具有新的技巧,但由于Outlook的行为类似于Singleton,因此不会创建其他Outlook实例。
我仅在安装了64位Office 365的情况下对其进行了测试。