C# 4.0 从其他office客户端调用邮件时,Outlook 2010加载项的行为异常
我真的需要你的帮助 我写了一个添加,在发送邮件时向邮件的主题行添加一些文本。它还通过PropertyAccessor在电子邮件的属性中设置相同的值。当通过Outlook界面创建电子邮件时,这项功能非常有效 我遇到的问题是,当用户使用excel时,决定从excel 2010->File->Save&send->send as attachment菜单项将电子表格作为附件发送 这将像您预期的那样打开outlook 2010邮件编辑器,用户可以寻址电子邮件并按正常发送,电子邮件将正常发送。问题是,电子邮件编辑器在发送后并不像您预期的那样关闭C# 4.0 从其他office客户端调用邮件时,Outlook 2010加载项的行为异常,c#-4.0,outlook-addin,C# 4.0,Outlook Addin,我真的需要你的帮助 我写了一个添加,在发送邮件时向邮件的主题行添加一些文本。它还通过PropertyAccessor在电子邮件的属性中设置相同的值。当通过Outlook界面创建电子邮件时,这项功能非常有效 我遇到的问题是,当用户使用excel时,决定从excel 2010->File->Save&send->send as attachment菜单项将电子表格作为附件发送 这将像您预期的那样打开outlook 2010邮件编辑器,用户可以寻址电子邮件并按正常发送,电子邮件将正常发送。问题是,电子
我正在使用Globals.ThisAddIn.Application.ItemSend事件对电子邮件进行更改。在调试时我还注意到,在发送时,此事件会触发几次。此事件的cancel参数在执行过程中始终为false。终于找到了一些似乎有效的方法 以防链接像他们可能做的那样失效 这是包装纸
namespace OutlookAddIn
{
// Eventhandler used to correctly clean up resources.
// <param name="id">The unique id of the Inspector instance.</param>
internal delegate void InspectorWrapperClosedEventHandler(Guid id);
// The base class for all inspector wrappers.
internal abstract class InspectorWrapper
{
// Event notification for the InspectorWrapper.Closed event.
// This event is raised when an inspector has been closed.
// The unique ID that identifies an inspector window.
protected InspectorWrapper(Inspector inspector)
{
Id = Guid.NewGuid();
Inspector = inspector;
// Register Inspector events here
((InspectorEvents_10_Event) Inspector).Close += InspectorClose;
((InspectorEvents_10_Event) Inspector).Activate += Activate;
(Inspector).Deactivate += Deactivate;
(Inspector).BeforeMaximize += BeforeMaximize;
(Inspector).BeforeMinimize += BeforeMinimize;
(Inspector).BeforeMove += BeforeMove;
(Inspector).BeforeSize += BeforeSize;
(Inspector).PageChange += PageChange;
// Initialize is called to give the derived wrappers.
Initialize();
}
public Guid Id { get; private set; }
// The Outlook Inspector instance.
public Inspector Inspector { get; private set; }
public event InspectorWrapperClosedEventHandler Closed;
// .ctor
// <param name="inspector">The Outlook Inspector instance that should be handled.</param>
// Event handler for the Inspector Close event.
private void InspectorClose()
{
// Call the Close Method - the derived classes can implement cleanup code
// by overriding the Close method.
Close();
// Unregister Inspector events.
((InspectorEvents_10_Event) Inspector).Close -= InspectorClose;
// Clean up resources and do a GC.Collect().
Inspector = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Raise the Close event.
if (Closed != null)
{
Closed(Id);
}
}
protected virtual void Initialize()
{}
// Method is called when another page of the inspector has been selected.
// <param name="ActivePageName">The active page name by reference.</param>
protected virtual void PageChange(ref string ActivePageName)
{}
// Method is called before the inspector is resized.
// <param name="Cancel">To prevent resizing, set Cancel to true.</param>
protected virtual void BeforeSize(ref bool Cancel)
{}
// Method is called before the inspector is moved around.
// <param name="Cancel">To prevent moving, set Cancel to true.</param>
protected virtual void BeforeMove(ref bool Cancel)
{}
// Method is called before the inspector is minimized.
// <param name="Cancel">To prevent minimizing, set Cancel to true.</param>
protected virtual void BeforeMinimize(ref bool Cancel)
{}
// Method is called before the inspector is maximized.
// <param name="Cancel">To prevent maximizing, set Cancel to true.</param>
protected virtual void BeforeMaximize(ref bool Cancel)
{}
// Method is called when the inspector is deactivated.
protected virtual void Deactivate()
{}
// Method is called when the inspector is activated.
protected virtual void Activate()
{}
// Derived classes can do a cleanup by overriding this method.
protected virtual void Close()
{}
// This factory method returns a specific InspectorWrapper or null if not handled.
// <param name=”inspector”>The Outlook Inspector instance.</param>
// Returns the specific wrapper or null.
public static InspectorWrapper GetWrapperFor(Inspector inspector)
{
// Retrieve the message class by using late binding.
string messageClass = inspector.CurrentItem.GetType().InvokeMember("MessageClass", BindingFlags.GetProperty,
null, inspector.CurrentItem, null);
// Depending on the message class, you can instantiate a
// different wrapper explicitly for a given message class by
// using a switch statement.
switch (messageClass)
{
case "IPM.Contact":
return new ContactItemWrapper(inspector);
case "IPM.Journal":
return new ContactItemWrapper(inspector);
case "IPM.Note":
return new MailItemWrapper(inspector);
case "IPM.Post":
return new PostItemWrapper(inspector);
case "IPM.Task":
return new TaskItemWrapper(inspector);
}
// Or, check if the message class begins with a specific fragment.
if (messageClass.StartsWith("IPM.Contact.X4U"))
{
return new X4UContactItemWrapper(inspector);
}
// Or, check the interface type of the item.
if (inspector.CurrentItem is AppointmentItem)
{
return new AppointmentItemWrapper(inspector);
}
// No wrapper is found.
return null;
}
}
// Derive a wrapper for each message class/item type.
}
namespace-OutlookAddIn
{
//Eventhandler用于正确清理资源。
//检查器实例的唯一id。
内部委托无效检查器WrapperClosedEventHandler(Guid id);
//所有inspector包装器的基类。
内部抽象类检查器包装器
{
//InspectorWrapper.Closed事件的事件通知。
//当检查器关闭时引发此事件。
//标识检查器窗口的唯一ID。
受保护的检验员包装(检验员)
{
Id=Guid.NewGuid();
检查员=检查员;
//在此处注册检查器事件
((InspectorEvents_10_Event)Inspector)。关闭+=检查关闭;
((InspectorEvents_10_Event)Inspector).激活+=激活;
(检验员).停用+=停用;
(检查员).beforemized+=beforemized;
(检查员).BeforeMimize+=BeforeMimize;
(检查员).移动前+=移动前;
(检查员).BeforeSize+=BeforeSize;
(检查器).页面更改+=页面更改;
//调用Initialize以提供派生包装器。
初始化();
}
公共Guid Id{get;private set;}
//Outlook检查器实例。
公共检查器检查器{get;private set;}
公共事件检查器WrapperClosedEventHandler关闭;
//博士
//应处理的Outlook Inspector实例。
//检查器关闭事件的事件处理程序。
私有无效检查器关闭()
{
//调用Close方法-派生类可以实现清理代码
//通过重写Close方法。
Close();
//注销检查器事件。
((InspectorEvents_10_Event)Inspector)。关闭-=检查关闭;
//清理资源并执行GC.Collect()。
Inspector=null;
GC.Collect();
GC.WaitForPendingFinalizers();
//提出关闭事件。
如果(关闭!=null)
{
已关闭(Id);
}
}
受保护的虚拟空初始化()
{}
//方法在选择检查器的另一个页面时调用。
//通过引用指定活动页名称。
受保护的虚拟void页面更改(引用字符串ActivePageName)
{}
//方法在调整检查器大小之前调用。
//要防止调整大小,请将“取消”设置为true。
大小之前受保护的虚拟空间(参考布尔取消)
{}
//方法在移动检查器之前调用。
//要防止移动,请将“取消”设置为true。
移动前受保护的虚拟无效(参考bool取消)
{}
//方法在最小化检查器之前调用。
//要防止最小化,请将“取消”设置为true。
最小化前受保护的虚拟无效(参考布尔取消)
{}
//方法在最大化检查器之前调用。
//要防止最大化,请将“取消”设置为true。
最大化前受保护的虚拟无效(参考布尔取消)
{}
//方法在禁用检查器时调用。
受保护的虚拟无效停用()
{}
//方法在激活检查器时调用。
受保护的虚拟void Activate()
{}
//派生类可以通过重写此方法进行清理。
受保护的虚拟void Close()
{}
//此工厂方法返回特定的InspectorWrapper,如果未处理,则返回null。
//Outlook检查器实例。
//返回特定的包装器或null。
公共静态检查器包装器GetWrapperFor(检查器检查器)
{
//使用后期绑定检索消息类。
字符串messageClass=inspector.CurrentItem.GetType().InvokeMember(“messageClass”,BindingFlags.GetProperty,
null,inspector.CurrentItem,null);
//根据消息类,您可以实例化
//指定消息类的不同包装器
//使用switch语句。
开关(messageClass)
{
案例“IPM.Contact”:
返回新的ContactItemWrapper(检查员);
案例“IPM.Journal”:
返回新的ContactItemWrapper(检查员);
案例“IPM.注”:
返回新的MailItemWrapper(inspector);
案例“IPM.Post”:
退回新岗位(检验员);
案例“IPM.Task”:
返回新的TaskItemWrapper(inspector);
}
//或者,检查消息类是否以特定片段开头。
if(messageClass.StartsWith(“IPM.Contact.X4U”))
{
返回新的X4U ContactItemWrapper(检验员);
}
//或者,检查项目的接口类型。
如果(inspector.CurrentItem为任命项)
{
internal class MailItemWrapper : InspectorWrapper
{
// The Object instance behind the Inspector, which is the current item.
public MailItemWrapper(Inspector inspector)
: base(inspector)
{
// Get the item in the current Inspector.
Item = (MailItem) Inspector.CurrentItem;
// Register Item events.
Item.Open += Item_Open;
Item.Write += Item_Write;
}
public MailItem Item { get; private set; }
// This method is called when the item is visible and the UI is initialized.
// <param name="Cancel">When you set this property to true, the Inspector is closed.</param>
private void Item_Open(ref bool Cancel)
{
// TODO: Implement something
}
// This method is called when the item is saved.
// <param name="Cancel">When set to true, the save operation is cancelled.</param>
private void Item_Write(ref bool Cancel)
{
//TODO: Implement something
}
// The Close method is called when the inspector has been closed.
// Do your cleanup tasks here.
// The UI is gone, cannot access it here.
protected override void Close()
{
// Unregister events.
Item.Write -= Item_Write;
Item.Open -= Item_Open;
// Release references to COM objects.
Item = null;
// Set item to null to keep a reference in memory of the garbage collector.
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
public partial class ThisAddIn
{
// Holds a reference to the Application.Inspectors collection.
// Required to get notifications for NewInspector events.
private Inspectors _inspectors;
// A dictionary that holds a reference to the inspectors handled by the add-in.
private Dictionary<Guid, InspectorWrapper> _wrappedInspectors;
private void ThisAddInStartup(object sender, EventArgs e)
{
_wrappedInspectors = new Dictionary<Guid, InspectorWrapper>();
_inspectors = Globals.ThisAddIn.Application.Inspectors;
_inspectors.NewInspector += WrapInspector;
// Also handle existing Inspectors
// (for example, double-clicking a .msg file).
foreach (Inspector inspector in _inspectors)
{
WrapInspector(inspector);
}
}
// Wrap an Inspector, if required, and store it in memory to get events of the wrapped Inspector.
// <param name="inspector">The Outlook Inspector instance.</param>
private void WrapInspector(Inspector inspector)
{
var wrapper = InspectorWrapper.GetWrapperFor(inspector);
if (wrapper != null)
{
// Register the Closed event.
wrapper.Closed += WrapperClosed;
// Remember the inspector in memory.
_wrappedInspectors[wrapper.Id] = wrapper;
}
}
// Method is called when an inspector has been closed.
// Removes reference from memory.
// <param name="id">The unique id of the closed inspector</param>
private void WrapperClosed(Guid id)
{
_wrappedInspectors.Remove(id);
}
private void ThisAddInShutdown(object sender, EventArgs e)
{
// Clean up.
_wrappedInspectors.Clear();
_inspectors.NewInspector -= WrapInspector;
_inspectors = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
Startup += ThisAddInStartup;
Shutdown += ThisAddInShutdown;
}
#endregion
}