我的C#应用程序允许用户选择要发送电子邮件的文件。他们需要从他们的Outlook / Exchange联系人中选择收件人,因为我们管理/同步公司的联系人列表。
发送后我需要捕获msg文件并使用收件人信息将其保存到某处。
收件人信息在发送期间不可用,因此我找到了一些代码来使用已发送文件夹ItemAdded事件。
这一切都完美无缺,直到有人在没有已经打开的情况下运行它,在这种情况下,事件永远不会被触发。 Application.ItemSend()
,Inspector.Close()
等全部开火,但不是获取收件人信息所需的那个。
任何人都对为什么这不起作用有任何想法?
注意:有几个关于类似问题的问题,他们让Items变量超出范围。我实际上正在返回这个并等待它被执行,当Outlook打开并最终事件触发时,它正常工作。
这是我的方法,Outlook只是Microsoft.Office.Interop.Outlook
的别名。
public Outlook.Items Send(string subject, string body) {
try {
// Create the Outlook application.
Outlook.Application oApp = new Outlook.Application();
Outlook.MAPIFolder sentFolder = oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Outlook.Items itmsSentFolder = sentFolder.Items;
itmsSentFolder.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
_inspector = oMsg.GetInspector;
oMsg.Subject = subject;
oMsg.Body = body;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
foreach (string file in _attachments) {
Outlook.Attachment oAttach = oMsg.Attachments.Add(file, iAttachType, 1, Path.GetFileName(file));
}
((Outlook.InspectorEvents_10_Event)_inspector).Close += new Outlook.InspectorEvents_10_CloseEventHandler(Inspector_Close);
oMsg.Mileage = MESSAGE_FLAG;
oMsg.Display(false);
oMsg = null;
oApp = null;
return itmsSentFolder;
} catch (Exception ex) {
_log.Error("Error sending attachments to Outlook", ex);
throw;
}
}
更新
public Outlook.Items Send(string subject, string body) {
try {
_sent = false;
try {
_oApp = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
_closeOutlook = false;
} catch {
_oApp = new Outlook.Application();
_closeOutlook = true;
}
if (_oApp.Explorers.Count <= 0) {
_oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Display();
_oApp.ActiveExplorer().WindowState = Outlook.OlWindowState.olMinimized;
}
_sentFolder = _oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
_itmsSentFolder = _sentFolder.Items;
_itmsSentFolder.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
_oMsg = (Outlook.MailItem)_oApp.CreateItem(Outlook.OlItemType.olMailItem);
_inspector = _oMsg.GetInspector;
_oMsg.Subject = subject;
_oMsg.Body = body;
((Outlook.ItemEvents_10_Event)_oMsg).Send += new Microsoft.Office.Interop.Outlook.ItemEvents_10_SendEventHandler(MailItem_Send);
((Outlook.ItemEvents_10_Event)_oMsg).Write += new Microsoft.Office.Interop.Outlook.ItemEvents_10_WriteEventHandler(MailItem_Write);
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
foreach (string file in _attachments) {
Outlook.Attachment oAttach = _oMsg.Attachments.Add(file, iAttachType, 1, Path.GetFileName(file));
}
((Outlook.InspectorEvents_10_Event)_inspector).Close += new Outlook.InspectorEvents_10_CloseEventHandler(Inspector_Close);
_oMsg.Mileage = MESSAGE_FLAG;
_oMsg.Display(true);
} catch (Exception ex) {
_log.Error("Error sending attachments to Outlook", ex);
throw;
}
return _itmsSentFolder;
}
答案 0 :(得分:0)
垃圾收集器刷过源对象。即ItemAdd事件未被触发,因为源对象的范围受try / catch块的限制。您需要在全局范围内声明对象并确保它仍处于活动状态。
P.S。请注意,当同时添加多个项目(超过16个)时,不会触发ItemAdd事件。这是Outlook中一个众所周知的问题。
答案 1 :(得分:0)
使用解决方案为我的原始帖子添加了更新。这可能是Outlook 2013的一个问题,因为我发现了一个类似的旧产品,现在它应该等待ItemAdded事件时挂起。
注意:之后必须清理所有引用,其中包括知道是否需要在完成后关闭Outlook。调用oApp.Quit()将退出Outlook,即使它已经打开。