【问题标题】:Outlook 2010 AddIn behaves weirdly when mail invoked from other office client从其他 Office 客户端调用邮件时,Outlook 2010 插件行为异常
【发布时间】:2012-12-04 15:26:06
【问题描述】:

我真的需要这方面的帮助。

我写了一个添加,在发送时向电子邮件的主题行添加一些文本,它还通过 PropertyAccessor 在电子邮件的属性中设置相同的值。当通过 Outlook 界面创建电子邮件时,这非常有效。

我遇到的问题是,当用户使用 excel 并决定将电子表格作为附件从 Excel 2010 -> 文件 -> 保存并发送 -> 作为附件菜单项发送时。

这将像您期望的那样打开 Outlook 2010 邮件编辑器,用户可以正常处理电子邮件并按发送,电子邮件将正常发送。问题是电子邮件编辑器在发送后没有按您的预期关闭。

我正在使用 Globals.ThisAddIn.Application.ItemSend 事件对电子邮件进行更改。我在调试时也注意到这个事件在发送时会触发几次。该事件的cancel参数在执行过程中始终为false。

【问题讨论】:

    标签: c#-4.0 outlook-addin


    【解决方案1】:

    终于找到了似乎可行的东西

    Developing an Inspector Wrapper for Outlook 2010

    如果链接失效,他们可能会这样做

    这是包装器

    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.
    }
    

    这是一个覆盖示例

    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();
        }
    }
    

    这里是 ThisAddin 类

    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
    }
    

    如果链接断开,应该有足够的空间让人们摆脱困境

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多