none
knowing when a specific mail item has been sent RRS feed

  • Question

  • I'm writing a WPF application using Outlook interop and I'm trying to send email through Outlook using the PIA assemblies. However, instead of creating my own editor dialog, I am just using the default email editor provided by Outlook. Everything works fine, but the problem is, I don't know how to determine if the user actually sent an email or cancelled out of and/or closed the editor dialog?

     

    Here is the code I've written:

     

    Code Snippet

    private void EmailHyperlink_Click(object sender, RoutedEventArgs e)

    {

        Hyperlink link = sender as Hyperlink;

     

        try

        {

            // Create the new mail item

            OUTLOOK.MailItem mailItem = new OUTLOOK.ApplicationClass().CreateItem(OUTLOOK.OlItemType.olMailItem) as OUTLOOK.MailItem;

            mailItem.To = link.Tag.ToString();

     

            mailItem.Display(true);

     

            if (mailItem.Sent)

            {

                // Special logic in response to the mail item being sent

            }

        }

     

        catch (Exception x)

        {

            MessageBox.Show(x.Message, "Error Sending Message");

        }

    }

     

     

    The Display method does not return any kind of dialog result and when I access mailItem.Sent after the dialog closes, I get a COMException stating "The item has been moved or deleted."

     

    What do I need to do to in order to know that the user actually sent a message and didn't cancel out of the Outlook dialog; i.e., how do I know the specific mail item created has been sent?

    Friday, March 21, 2008 6:13 PM

Answers

  • Hi,

     

    To determine if the user actually sent the email, you can listen to the email’s Send event.(You need to declare mailItem in class level scope). Codes:

    Code Snippet

    OUTLOOK.MailItem mailItem = null;

     

    private void EmailHyperlink_Click(object sender, RoutedEventArgs e)

    {

        Hyperlink link = sender as Hyperlink;

     

        try

        {

           mailItem = new OUTLOOK.ApplicationClass().CreateItem(OUTLOOK.OlItemType.olMailItem) as OUTLOOK.MailItem;

                mailItem.Display(missing);

                ((Outlook.ItemEvents_10_Event)mailItem).Send += new Microsoft.Office.Interop.Outlook.ItemEvents_10_SendEventHandler(ThisAddIn_Send);

                ((Outlook.ItemEvents_10_Event)mailItem).Close += new Microsoft.Office.Interop.Outlook.ItemEvents_10_CloseEventHandler(ThisAddIn_Close);    }

    }

          

          void ThisAddIn_Close(ref bool Cancel)

          {

             MessageBox.Show("MailItem is closed");

          }

     

          void ThisAddIn_Send(ref bool Cancel)

          {

             MessageBox.Show("MailItem is Sent");

          }

     

     

     

     

    Thanks,

    Ji

     

    Tuesday, March 25, 2008 8:33 AM
    Moderator
  • To and Body are properties protected by the Outlook "object model guard." See http://www.outlookcode.com/article.aspx?ID=52 for various ways of dealing with them. Your options are more limited because you are building an external application, rather than an Outlook add-in.

    Wednesday, March 26, 2008 12:20 AM
    Moderator

All replies

  • Hi,

     

    To determine if the user actually sent the email, you can listen to the email’s Send event.(You need to declare mailItem in class level scope). Codes:

    Code Snippet

    OUTLOOK.MailItem mailItem = null;

     

    private void EmailHyperlink_Click(object sender, RoutedEventArgs e)

    {

        Hyperlink link = sender as Hyperlink;

     

        try

        {

           mailItem = new OUTLOOK.ApplicationClass().CreateItem(OUTLOOK.OlItemType.olMailItem) as OUTLOOK.MailItem;

                mailItem.Display(missing);

                ((Outlook.ItemEvents_10_Event)mailItem).Send += new Microsoft.Office.Interop.Outlook.ItemEvents_10_SendEventHandler(ThisAddIn_Send);

                ((Outlook.ItemEvents_10_Event)mailItem).Close += new Microsoft.Office.Interop.Outlook.ItemEvents_10_CloseEventHandler(ThisAddIn_Close);    }

    }

          

          void ThisAddIn_Close(ref bool Cancel)

          {

             MessageBox.Show("MailItem is closed");

          }

     

          void ThisAddIn_Send(ref bool Cancel)

          {

             MessageBox.Show("MailItem is Sent");

          }

     

     

     

     

    Thanks,

    Ji

     

    Tuesday, March 25, 2008 8:33 AM
    Moderator
  • Thank you, your solution worked. However how do I continue to access the mail item after it's been sent without Outlook opening a dialog containing this message:

     

    "A program is trying to access e-mail address information stored in Outlook. If this is unexpected, click Deny and verify your antivirus software is up-to-date."

     

    I'm then forced to click the "Allow" button in the dialog in order for the application to continue. Here is the event handler where I'm trying to access some of the data contained in the sent mail item.

     

    Code Snippet

    private void OutlookMailItem_Send(ref bool Cancel)

    {

        string recipient = _mailItem.To;

        string body = _mailItem.Body;

     

        // Do stuff with the data contained in the sent mail item

    }

    Tuesday, March 25, 2008 10:29 PM
  • To and Body are properties protected by the Outlook "object model guard." See http://www.outlookcode.com/article.aspx?ID=52 for various ways of dealing with them. Your options are more limited because you are building an external application, rather than an Outlook add-in.

    Wednesday, March 26, 2008 12:20 AM
    Moderator
  • Well that's disappointing but thank you for the resource; I'll see what I can do.

     

    Thursday, March 27, 2008 10:25 PM
  • I have yet another issue and I hope this is still the right forum: I am trying to use very simple Outlook interop from an XBAP. The application is signed as a full trust application and when I debug the application, all interop logic works fine, but when I publish and run the application, I get a COM error, 80080005 to be specific.

     

    I've done some research on the error number and the only information I can find is in an ASP.NET 2.0 context and it has to do with the internet user not having sufficient permissions to access COM. But this error is occurring in a full trust XBAP which doesn't make any sense to me?

     

    Thursday, April 3, 2008 6:16 PM
  • Dear Friends,

    I have the following code which i used to send mails (in ASP.NET 2.0)  to the selected recipients. this code is working fine. Here when user click on the semd mail  button ouloook window is opened where the user can change the mail contents and  send it. but i am unable check whether user has sent the mail or closed the window so that i can increment a mail counter into a table.

     protected void btnMail_Click(object sender, EventArgs e)

        {

            // Create the Outlook application.

            Outlook.Application oApp = new Outlook.Application();

     

            // Get the NameSpace and Logon information.

            Outlook.NameSpace oNS = oApp.GetNamespace("mapi");

     

            // Log on by using a dialog box to choose the profile.

            oNS.Logon(Missing.Value, Missing.Value, true, true);

     

            // Alternate logon method that uses a specific profile.

            // TODO: If you use this logon method, 

            //  change the profile name to an appropriate value.

            //oNS.Logon("YourValidProfile", Missing.Value, false, true); 

     

            // Create a new mail item.

     

     

            Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);

     

     

     

            // Set the subject.

            oMsg.Subject = "Reminder for Non Complied Activities";

            string PId = string.Empty;

            string SId = string.Empty;

            string Id = string.Empty;

            string EName = string.Empty;

            ArrayList values = new ArrayList();

            Boolean chkP = true, chkS = true, ch = false;

     

            // Set HTMLBody.

     

            sHtml = "<HTML>\n";

            sHtml = sHtml + "<HEAD>\n";

            sHtml = sHtml + "<TITLE>Sample GIF</TITLE>\n";

            sHtml = sHtml + "</HEAD>\n";

     

            sHtml = sHtml + "<BODY>\n";

            sHtml = sHtml + "Dear All,\n<br/><br/>";

            sHtml = sHtml + "Find below the list of Non-Compliances pending on your parts.\n<br/><br/>";

            sHtml = sHtml + "<table border='1'><tr style='background-color:#A3C7FF;' align='center'><td>Activity id</td><td>Department</td><td>Name Of Compliance</td><td>Category</td>\n";

            sHtml = sHtml + "<td>Due Date</td><td>Compliance Date</td><td>Primary Responsible</td><td>Secondary Responsible</td><td>Status</td></tr>\n";        

     

            foreach (GridViewRow di in grdststus.Rows)

            {

                CheckBox chkBx = (CheckBox)di.FindControl("CheckBox1");

                if (chkBx != null && chkBx.Checked)

                {

                    ch = true;

                    PId = objData.GetEmailId(di.Cells[14].Text.ToString());

                    SId = objData.GetEmailId(di.Cells[15].Text.ToString());

                    if (values.Count == 0)

                    {

                        values.Add(PId);

                        Id = PId;

                        if (PId != SId)

                        {

                            values.Add(SId);

                            Id = Id + ";" + SId;

                        }

                    }

                    else

                    {

                        if (values.Count > 0)

                        {

                            for (int i = 0; i < values.Count; i++)

                            {

                                chkP = true;

                                if (values[i].ToString() == PId.ToString())

                                {

                                    chkP = false;

                                    break;

                                }

                            }

                            if (chkP == true)

                            {

                                values.Add(PId);

                                Id = Id + ";" + PId;

                            }

                            for (int i = 0; i < values.Count; i++)

                            {

                                chkS = true;

                                if (values[i].ToString() == SId.ToString())

                                {

                                    chkS = false;

                                    break;

                                }

                            }

                            if (chkS == true)

                            {

                                values.Add(SId);

                                Id = Id + ";" + SId;

                            }

     

                        }

                    }

                    sHtml = sHtml + "<tr><td>" + di.Cells[2].Text.ToString() + "</td><td>" + di.Cells[3].Text.ToString() + "</td><td>" + di.Cells[4].Text.ToString() + "</td><td>" + di.Cells[6].Text.ToString() + "</td>\n";

                    sHtml = sHtml + "<td>" + di.Cells[7].Text.ToString() + "</td><td>" + di.Cells[8].Text.ToString() + "</td><td>" + di.Cells[9].Text.ToString() + "</td><td>" + di.Cells[10].Text.ToString() + "</td><td>" + di.Cells[11].Text.ToString() + "</td></tr>\n";

                    using (ObjConnect = new SqlConnection(conn))

                    {

                        string cmdTxt = string.Empty;

                        SqlDataAdapter adp = new SqlDataAdapter();

                        adp.SelectCommand = new SqlCommand("Select * from TblRemCount where rowid =" + Convert.ToInt32(di.Cells[13].Text.ToString()), ObjConnect);

                        DataSet ds = new DataSet();

                        adp.Fill(ds);

                        if (ds.Tables[0].Rows.Count > 0)

                        {

                            //Update

                            int rId = Convert.ToInt32(ds.Tables[0].Rows[0]["Reminder"].ToString());

                            cmdTxt = "update TblRemCount set Reminder=" + (rId + 1) + " where rowid=" + Convert.ToInt32(di.Cells[13].Text.ToString());

                            SqlCommand cmd = new SqlCommand(cmdTxt, ObjConnect);

                            ObjConnect.Open();

                            cmd.ExecuteNonQuery();

                        }

                        else

                        {

                            //Insert

                            cmdTxt = "Insert into TblRemCount values(" + Convert.ToInt32(di.Cells[13].Text.ToString()) + "," + 1 + ")";

                            SqlCommand cmd = new SqlCommand(cmdTxt, ObjConnect);

                            ObjConnect.Open();

                            cmd.ExecuteNonQuery();

                        }

                    }

                }            

            }

            EName = objData.GetCurrentEmpName(Session["EmpCode"].ToString());

            sHtml = sHtml + "</table>";

            sHtml = sHtml + "<br/><br/>You are requested to take the corrective action.<br/><br/>\n";

            sHtml = sHtml + "Regards,<br/>";

            sHtml = sHtml + EName+"\n";

            sHtml = sHtml + "</BODY>\n";

            sHtml = sHtml + "</HTML>";        

            oMsg.HTMLBody = sHtml;

     

            if (ch == false)

                lblError1.Text = "Please Select Atleast one activity to send.";

            else

            {

                lblError1.Text = "";

                // Add a recipient.

                Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;

                // TODO: Change the recipient in the next line if necessary.

                Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(Id);

                oRecip.Resolve();

     

                // Send.

                oMsg.Display(true);

     

                // Log off.

                // Clean up.

                oNS.Logoff();

                oRecip = null;

                oRecips = null;

                oMsg = null;

                oNS = null;

                oApp = null;

            }

     

    Please help me how to determine whether the mail is sent or not.

    Regrads,

    Ghazi

    Wednesday, March 16, 2011 7:17 AM