none
Outlook 2010 Addin: Read signature during send event OR get only own current email body while writing an answer RRS feed

  • Question

  • Hello community, 

    first of all I know that I asked the same question in German before but I really hope to get some answers. I even asked on stackoverflow and addin-express and no one could really help me.

    I want to develop an addin for Outlook which blocks sending an email if the default signature is not contained or if it was changed. 

    The check for this should happen right after the user hit the button "send" which would be the send event. 

    I know that the signature is contained in a bookmark called "_MailAutoSig". As long as the mail is not sent I can read from this bookmark like:

    document.Bookmarks.ShowHidden = true;
    var bkmText = document.Bookmarks["_MailAutoSig"].Range.Text;

    The problem I have is that as soon as you are in the send event this bookmark can't be found anymore. Is there a way to read from this bookmark during the send event or do you guys have any other idea how I could solve my problem?

    I had a second idea to just check if the mailItem.Body contains the signature but the problem with that is that this property contains all the previous messages too if it is a forwarded email or an answer and I only want to check my own current body. I tried using mailItem.HTMLBody to check when the next message starts using html tags and regular expressions but this method is not perfect. I would prefer method one.

    I am very thankful for any ideas and tips since I have been looking and trying many things for weeks. Thank you in advance.

    Johannes

    Wednesday, September 28, 2016 9:07 AM

All replies

  • Hello Johannes,

    What code do you have now?

    Looks like you need to handle the ItemSend event of the Application class which is fired whenever an Microsoft Outlook item is sent, either by the user through an Inspector (before the inspector is closed, but after the user clicks the Send button) or when the Send method for an Outlook item, such as MailItem, is used in a program.

    Typically you can find the signatures in the AppData folder, see Add the default outlook signature in the email generated for more information.

    By default you can find the Signatures folder in the following location;

    • Windows XP
      C:\Documents and Settings\%username%\Application Data\Microsoft\Signatures
    • Windows 8, Windows 7 and Windows Vista
      C:\Users\%username%\AppData\Roaming\Microsoft\Signatures

     Look for the following files and folders;

    • <signature_name>.htm
      This file is used when creating HTML messages.
    • <signature_name>.rtf
      This file is used when creating Rich Text messages.
    • <signature_name>.txt
      This file is used when creating Plain Text message.
    • <signature_name>_files
      This folder is used in Outlook 2007, 2010 and 2013 to store supporting files for your signature such as formatting, images and/or business cards (vcf-files).

    Finally, you may find the How To: Change an Outlook e-mail message before sending using C# or VB.NET article helpful.


    [custom.development]

    Wednesday, September 28, 2016 10:03 AM
  • Hello Eugene, 

    thank you for your response. I tried the code from this link before and that did not help me. It seems like that there is no bookmark anymore as soon as I am in the ItemSend event.

    This is my current code (simplified):

    void adxOutlookEvents_ItemSend(object sender, ADXOlItemSendEventArgs e)
    {
    	Outlook.MailItem item = e.Item as Outlook.MailItem;
    	if (item == null)
    	{
    		return;
    	}
    
    	if (item.MessageClass != "IPM.Note")
    	{
    		return;
    	}
    
    	BookmarkTest(item);
    }
    
    void BookmarkTest(Outlook.MailItem item)
    {
    	Outlook.Inspector inspector = item.GetInspector;
    	Word.Document document = (Word.Document)inspector.WordEditor;
    	document.Bookmarks.ShowHidden = true;
    	Word.Bookmarks bookmarks = document.Bookmarks;
    	foreach (Word.Bookmark bookmark in bookmarks)
    	{
    		MessageBox.Show(bookmark.Name);
    	}
    	if (bookmarks.Count < 1)
    	{
    		MessageBox.Show("no bookmarks...");
    	}
    }

    Also I know the signature text. I just want to extract the bookmark so I can compare the extracted bookmark text with the signature text I know to see if the email message contains the signature or if it was changed somehow. I hope I could explain that a bit better this time.

    On stackoverflow I read the following:

    The problem is that Microsoft converts the "Office HTML" (I'm not sure the proper term) to normal HTML before it fires the ItemSend() event, which causes the _MailAutoSig bookmark to disappear.

    The only way to get the _MailAutoSig bookmark back is to first CANCEL the ItemSend() event, then fire off a timer to run a function which will in turn access the email object and manipulate it how you want, add a user property to mark the email has been processed, and then send the email again.

    This is what I will try next. Maybe this is the reason why the bookmark seems to be gone as soon as I am in the send event.

    Best regards

    Johannes

    Wednesday, September 28, 2016 10:23 AM
  • Johannes,

    That is the case. Also you may try to handle the Send event of the MailItem class which is fired when the user selects the Send action for an item, or when the Send method is called for the item.


    [custom.development]

    Wednesday, September 28, 2016 10:44 AM
  • Hello Eugene, 

    I am sorry but I am confused. I thought I was handling the Send event already (adxOutlookEvents_ItemSend). Is there a different ItemSend event? Where can I find it and how can I use that? Does this come before the ItemSend event I used?

    Also I tried using a timer (Sleep since it was easier and faster for testing) and canceling the mailItem send event first and then accessing the copy of the mailItem (modItem) to check for the bookmark but that did not seem to work either.

    That is the code I used:

    Outlook.MailItem modItem;
    
    void adxOutlookEvents_ItemSend(object sender, ADXOlItemSendEventArgs e)
    {
    	Outlook.MailItem item = e.Item as Outlook.MailItem;
    	if (item == null)
    	{
    		return;
    	}
    
    	if (item.MessageClass != "IPM.Note")
    	{
    		return;
    	}
    
    	modItem = item;
    	e.Cancel = true;
    
    	Thread.Sleep(5000);
    	BookmarkTest();
    }
    
    void BookmarkTest()
    {
    	Outlook.Inspector inspector = modItem.GetInspector;
    	Word.Document document = (Word.Document)inspector.WordEditor;
    	document.Bookmarks.ShowHidden = true;
    	Word.Bookmarks bookmarks = document.Bookmarks;
    	foreach (Word.Bookmark bookmark in bookmarks)
    	{
    		MessageBox.Show(bookmark.Name);
    	}
    	if (bookmarks.Count < 1)
    	{
    		MessageBox.Show("no bookmarks...");
    	}
    }

    Best regards

    Johannes


    Wednesday, September 28, 2016 12:33 PM
  • Johannes,

    ItemSend belongs to the Application class, the Send one comes from the MailItem class. The Send one fires before the ItemSend one typically.

    Due to the fact that you use Add-in Express, see Outlook Item events explained: C#, VB.NET .


    [custom.development]

    Wednesday, September 28, 2016 12:58 PM
  • Thank you Eugene, 

    I downloaded the C# project from that link and changed the ProcessSend event a little bit:

    public override void ProcessSend(ADXCancelEventArgs e)
            {
                if (ItemObj is Outlook._MailItem)
                {
                    Outlook._MailItem mail = (Outlook._MailItem)ItemObj;
    
                    Outlook.Inspector inspector = mail.GetInspector;
                    Word.Document document = (Word.Document)inspector.WordEditor;
                    document.Bookmarks.ShowHidden = true;
                    Word.Bookmarks bookmarks = document.Bookmarks;
    
                    foreach (Word.Bookmark bookmark in bookmarks)
                    {
                        MessageBox.Show(bookmark.Name);
                    }
                    if (bookmarks.Count < 1)
                    {
                        MessageBox.Show("no bookmarks...");
                    }
                }
            }

    Is that the event you were talking about? I can confirm that this event fires before the adxOutlookEvents_ItemSend event but still it seems that the bookmark is gone before I can read from it. 

    Do I have an error in my code maybe? Using the above code results in "no bookmarks..." as well.

    Best regards

    Johannes


    Wednesday, September 28, 2016 1:43 PM
  • Johannes,

    Did you try to run the code in the button's Click event handler while the inspector is still open? Do you get the same results or not?


    [custom.development]

    Wednesday, September 28, 2016 2:18 PM
  • Bookmarks.Count will be 0, but "_MailAutoSig" bookmark will still be accessible using  document.Bookmarks("_MailAutoSig")

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, September 28, 2016 3:46 PM
  • Hello Eugene, 

    I found a very nice and helpful tool by addin-express which shows all events that happen live. With the help of this addin I could figure out the problem. 

    This is an extract of the events that happen after you clicked the send button:

    = 12:16:01  =  ADXOutlookItemEvents.PropertyChange. Property name is To
    = 12:16:01  =  ADXOutlookItemEvents.PropertyChange. Property name is CC
    = 12:16:01  =  ADXOutlookItemEvents.PropertyChange. Property name is BCC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is To
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is CC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is BCC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is To
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is CC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is BCC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is To
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is CC
    = 12:16:04  =  ADXOutlookItemEvents.PropertyChange. Property name is BCC
    = 12:16:04  =  ADXOutlookItemEvents.BeforeCheckNames ------ til here the bookmark "_MailAutoSig" is still found
    = 12:16:04  =  ADXOutlookItemEvents.BeforeCheckNames ------ from here on it is not found anymore
    = 12:16:09  =  ADXOutlookItemEvents.BeforeCheckNames
    = 12:16:09  =  ADXOutlookItemEvents.BeforeCheckNames
    = 12:16:09  =  ADXOutlookItemEvents.PropertyChange. Property name is ReceivedTime
    = 12:16:09  =  ADXOutlookItemEvents.Send.  MailItem with subject 'alskdjhlaskdjh'. 
    = 12:16:09  =  ADXOutlookAppEvents.ItemSend.  MailItem with subject 'alskdjhlaskdjh'. 
    = 12:16:09  =  ADXOutlookItemEvents.Write.  MailItem with subject 'alskdjhlaskdjh'. 


    As you can see neither the Send or the ItemSend method have the bookmark so I tried using the "BeforeCheckNames" event but apparently it gets called many times and the events even change according if you compose a new mail or reply to one. 

    The best way would really be to intercept the send button but I could not get this to work. 

    I could intercept the "reply" button. I downloaded the help files from MS but I could not find the correct IdMso to intercept the send button. 

    Can you give me an example how to use the send button's click event? 

    Thank you in advance

    Johannes

    Friday, September 30, 2016 10:41 AM
  • It seems like intercepting the send button is not supposed to work. 

    I want to use the BeforeCheckNames event for the check. My problem is that the user can click the button "CheckUserNames" which calls the same event. Is there a way to determine if the event BeforeCheckNames was called by the program itself or by the user? That would help me to check for the bookmark when the event occurs the first time. Since the user can call it too this does not really work.

    If there is a way to detect if the user or the program calls the event then I could use this method. 

    I would be happy for every hint and advice.

    Thanks in advance 

    Johannes

    Thursday, October 6, 2016 8:41 AM
  • Hi,

    Sorry for the delay.

    We have checked and it seems that there are not any suitable events to directly detect. And we could not detect whether BeforeCheckNames event is triggered by user or program.

    To work around your issue, I suggest to check if the number of signature string is changed in the HTMLbody. We could count the original number of the string in mailItem.Open or other proper events, then count the number in Send event. Compare them, and if it is changed, we could presume the default signature is edited.

    Regards,

    Celeste

    Monday, October 10, 2016 11:29 AM
    Moderator
  • Hey Celeste, 

    thank you for your answer. I assume that this will work but the problem I have would still exist. 

    Let's say the user receives the message during the send event: "Signature was change, pls add the default signature". Then you set e.Cancel to true and give the user a chance to correct the signature. 

    Now I would have to check for the signature again and the bookmark for the signature would be gone already.

    Therefore I think checking for the signature in the send event is too late. 

    I tried using the PropertyChanged event for BCC or BeforeChecknames but this does not really work.

    BCC changes when you insert a name but if you just reply to a message this property does not get changed. 

    BeforeCheckNames on the other hand gets called way too often. It gets called even when you create a task or want to save an email which I don't understand but it gets called...so that does not help me either.

    Now I am trying to intercept the send button directly before any event gets called but I do not really know how to do this yet.

    Best regards, 

    Johannes

    Tuesday, October 11, 2016 2:08 PM
  • Unfortunately, we are unable to custom the send button using outlook object model.

    If this is a new feature you want to include in the future, I would suggest you submit a feedback in the link below:

    https://outlook.uservoice.com/

     

    Besides, based on https://www.add-in-express.com/creating-addins-blog/2014/01/30/create-custom-send-button-outlook/  we could custom it by using windows API or create our own form region.

     

    Disclaimer: This response contains a reference to a third party World Wide Web site. Microsoft is providing this information as a convenience to you. Microsoft does not control these sites and has not tested any software or information found on these sites; therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information found there. There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet. 

     

    Wednesday, October 12, 2016 9:40 AM
    Moderator