Outlook VSTO - 从 Outlook VSTO 将文件 path/hyperlink 添加到 MailItem WordEditor

Outlook VSTO - Adding file path/hyperlink to MailItem WordEditor from Outlook VSTO

我遇到了以下问题。我有一个 window 打开并允许我 select 一些文件。 然后我可以右键单击 window 并选择将 selected 文件的路径附加到新邮件对话框。

工作流程是这样的:

  1. 我打开 windows 和 select 几个文件

  2. 右击,选择添加selected文件路径到MailItem

  3. 逻辑会检查是否有ActiveInspector

    3.1。如果有,我得到它的 CurrentItem as MailItem(因此,新邮件对话框存在,不需要创建)

    3.2。如果有none,我调用CreateItem(Microsoft.Office.Interop.OLItemType.olMailItem)创建 新邮件对话框然后我调用 MailItem.Display(false) 来显示 邮件项目对话框

  4. 接下来我遍历 selected 文件路径列表并将它们添加到新邮件对话框中。这很好用。

问题 如果我第二次打开 window 以 select 更多文件并将它们的路径添加到我之前打开的同一邮件对话框中,他们没有被添加。

代码如下:

public void AddFilePaths(List<string> paths)
{
    if (paths.Count > 0)
    {
        var inspector = MyAddIn.Application.ActiveInspector();
        MailItem mi = null;
        bool newMailItem = false;

        if (inspector != null)
        {
            // If new mail dialog is already open, just get it.
            // This is called on my 2nd attempt to add paths to new mail.
            // This MailItem is the same one created on 1st call in below
            // else block.  I confirmed that by adding some dummy email
            // Body in below else block, then checking for it here on 
            // 2nd call.  I think this proves that correct 
            // Inspector/MailItem is returned here.
            mi = MyAddIn.Application.ActiveInspector().CurrentItem as MailItem;
        }
        else
        {
            // create new mail dialog and display it
            // this is called on my 1st call to add paths to new mail
            mi = MyAddIn.Application.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
            mi.Body = "Dummy email body"; 
            newMailItem = true;
        }

        if (newMailItem)
        {
            mi.Display();
            inspector = MyAddIn.Application.ActiveInspector();
        }

        if (inspector != null)
        {
            foreach (var path in paths)
            {
                AddPathToActiveInspector(path);
            }
        }
    }
}

上面的代码调用此方法将路径添加到当前 ActiveInspector WordEditor:

public void AddPathToActiveInspector(string path)
{
    var inspector = MyAddIn.Application.ActiveInspector();
    dynamic we = inspector.WordEditor;
    dynamic word = we.Application;
    const string nl = "\n";

    // I have noticed that if I am debugging, this line will throw error
    // "COMException was unhandled by user code", "An exception of type
    // System.Runtime.Interop.Services.COMException occurred in 
    // System.Dynamic.dll but was not handled by user code:
    // Message: This command is not available
    // InnerException: null
    // I have also seen following error on 2nd attempt: "The TypeText    
    // method or property is not available because the document is
    // locked for editing."
    word.Selection.TypeText(nl);

    string address = path;
    string subAddress = "";
    string screenTip = "";
    string displayText = path; 
    word.ActiveDocument.Hyperlinks.Add(word.Selection.Range, ref address, ref subAddress, ref screenTip, ref displayText);
    word.Selection.TypeText(" "); 
}

每次您添加路径时,我都会简单地创建一封新电子邮件,以避免将路径添加到错误电子邮件的可能性,如果您打开多封电子邮件,可能会发生这种情况。

  1. 将对 Microsoft.Office.Interop.Word 的引用添加到您的项目
  2. 在 class 文件之上使用 Microsoft.Office.Interop.Word 添加

代码如下:

public void AddFilePaths(List<string> paths)
{
    if (paths.Count > 0)
    {
        MailItem  mi = ThisAddIn.Application.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
        mi.Display();
        if (mi!= null)
        {
            foreach (var path in paths)
            {
                AddPathsToNewEmailMessage(path);
            }
        }
    }
}

上面的代码调用这个方法来添加新邮件的路径WordEditor:

public void AddPathsToNewEmailMessage(string path)
{
    object link = url;
    object result = "url";
    object missing = Type.Missing;
    string nl = "\n";

    var inspector = ThisAddIn.Application.ActiveInspector();
    MailItem currMessage = inspector.CurrentItem;
    Word.Document doc = currMessage.GetInspector.WordEditor;
    Word.Selection sel = doc.Windows[1].Selection;
    doc.Hyperlinks.Add(sel.Range, ref result, ref missing, ref missing, ref link, ref missing);
    sel.EndKey(Word.WdUnits.wdLine);
    sel.InsertAfter(nl);
    sel.MoveDown(Word.WdUnits.wdLine);
}