Outlook blocking (freeze) when I create new email item with attachment? - c#

I'm currently building a plugin for Outlook using C#, but when I create new email item in the thread, if I add attachments to email, my Outlook is blocking the user interface (freezing) until email created.
If I don't add attachments that not blocking the user interface Outlook.
So how can I fix that (not blocking the user interface outlook)?
This my code:
In Ribbon.cs, I have function button click:
private void button2_Click(object sender, RibbonControlEventArgs e){
Globals.ThisAddIn.CheckProcessEmail();
}
and function CheckProcessEmail, I create new Thread:
public void CheckProcessEmail(){
Thread threadCheckTest = new Thread(CheckTest);
threadCheckTest.Start();
}
public static void CheckTest(){
Outlook.Application application = Globals.ThisAddIn.Application;
Outlook.MailItem item = application.CreateItem((Outlook.OlItemType.olMailItem));
Outlook.MAPIFolder sentBox = (Outlook.MAPIFolder)Globals.ThisAddIn.Application.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Outlook.MailItem email = (Outlook.MailItem)sentBox.Items.Add();
email.Subject = "Send Test";
email.HTMLBody = "<div class=WordSection1><p class=MsoNormal>sad<o:p></o:p></p></div><b>Strong</b><h1>Hello</h1>";
email.To = "a#test.com;b#test.com;c#test.com";
email.BCC = "cc#test.com";
email.Attachments.Add(#attachmentPath, Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing);
email.Save();
}

Related

If a mail arrives in Outlook, start another method (Outlook freezes) Interlop.Outlook C# WPF

I have the following method part of a WPF app:
// This method check Emails
public void CheckForEmails()
{
Outlook.Application application = null;
Outlook.NameSpace nameSpace = null;
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
application = new Outlook.Application();
nameSpace = application.GetNamespace("MAPI");
nameSpace.Logon("", "", Missing.Value, Missing.Value);
}
nameSpace = application.GetNamespace("MAPI");
Outlook.MAPIFolder inbox = nameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
//nameSpace.SendAndReceive(true);
var items = inbox.Items;
items.ItemAdd += AnyMethod;
}
//This method execute any method
public void AnyMethod(object Item)
{
MessageBox.Show("GOOD!");
}
//This is the is the xaml.cs view which initialize the emailAction class if the window is open
public partial class PageView : UserControl
{
public DownloadDeviceView()
{
InitializeComponent();
DataContext = new DownloadDeviceViewModel();
EmailAction emailAction = new EmailAction();
}
}
This method should execute the method AnyMethod() when a new e-mail is received in Outlook.
The problem is strangely always different: Sometimes everything works. Sometimes the method does not work at all. And sometimes Outlook freezes and nothing happens again.
You must define the source object at the global scope (class-level) to get the event fired and keep the object alive, i.e. preventing it from being swiped by the garbage collector. For example:
Outlook.Items = null;
Outlook.Application application = null;
Outlook.NameSpace nameSpace = null;
public void CheckForEmails()
{
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
application = new Outlook.Application();
nameSpace = application.GetNamespace("MAPI");
nameSpace.Logon("", "", Missing.Value, Missing.Value);
}
nameSpace = application.GetNamespace("MAPI");
Outlook.MAPIFolder inbox = nameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
//nameSpace.SendAndReceive(true);
items = inbox.Items;
items.ItemAdd += AnyMethod;
}
The ItemAdd event is not fired when you receive a lot of items at a time (more than sixteen). This is a known limitation of the Outlook object model and exists for decades.
I'd recommend using the NewMailEx event of the Application class instead. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item.
The NewMailEx event fires when a new message arrives in the Inbox and before client rule processing occurs. You can use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item.

how to automatically trigger a link in outlook email using VSTO

I'm trying to programmatically click on a link which creates an email with predefined subject,to,cc,bcc and body content of the email.My requirement is, If I select an Outlook mail item and click on “Approve via mail” in my Addin, the code will search for hyperlink “Click here to Approve” in the mail body and Automatically click on the hyperlink.
The hyperlink “Click here to Approve” creates an email with predefined subject,to,cc,bcc and body content of the email.
I'm not sure how to do it with VSTO as all the other solutions suggest using JQuery and Javascript
Object selObject = this.Application.ActiveExplorer().Selection[1];
Outlook._MailItem eMail = (Outlook._MailItem)
this.Application.CreateItem(Outlook.OlItemType.olMailItem);
eMail = ((Outlook._MailItem)selObject);
if(eMail.HTMLBody.Contains("Approve"))
{
}
I'm not sure what I can write in the IF segment of the code.Please Suggest.
Outlook doesn't provide anything for opening hyperlinks. You can use the the following code (Process.Start) for opening them in the default web browser:
Process.Start("your_hyperlink");
Or just create a Mail item progrmmatically in Outlook based on the info where the Approve button was clicked.
Outlook.MailItem mail = null;
Outlook.Recipients mailRecipients = null;
Outlook.Recipient mailRecipient = null;
try
{
mail = OutlookApp.CreateItem(Outlook.OlItemType.olMailItem)
as Outlook.MailItem;
mail.Subject = "A programatically generated e-mail";
mailRecipients = mail.Recipients;
mailRecipient = mailRecipients.Add("Eugene Astafiev");
mailRecipient.Resolve();
if (mailRecipient.Resolved)
{
mail.Send();
}
else
{
System.Windows.Forms.MessageBox.Show(
"There is no such record in your address book.");
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message,
"An exception is occured in the code of add-in.");
}
finally
{
if (mailRecipient != null) Marshal.ReleaseComObject(mailRecipient);
if (mailRecipients != null) Marshal.ReleaseComObject(mailRecipients);
if (mail != null) Marshal.ReleaseComObject(mail);
}
Take a look at the following articles for more information and samples:
How to create and show a new Outlook mail item programmatically: C#, VB.NET
How To: Create and send an Outlook message programmatically
How To: Fill TO,CC and BCC fields in Outlook programmatically
How To: Create a new Outlook message based on a template

Programming HyperlinkColumn to Send an Email WPF

I am attempting to program a DataGridHyperlinkColumn which contains user's emails to send a new email through outlook when clicking on the address. For now I am just using a test email instead of getting the contents of the column, but this is what I have so far;
<DataGridHyperlinkColumn Header="Email" Binding="{Binding Email}">
<DataGridHyperlinkColumn.ElementStyle>
<Style>
<EventSetter Event="Hyperlink.Click" Handler="OnEmailHyperlinkClick"/>
</Style>
</DataGridHyperlinkColumn.ElementStyle>
</DataGridHyperlinkColumn>
Then the handler in C#;
private void OnEmailHyperlinkClick(object sender, RoutedEventArgs e)
{
string subject = "My subject";
string emailTag = string.Format("mailto:someone#test.com?subject={0}", subject);
System.Diagnostics.Process.Start(emailTag);
}
At the moment this is providing strange behaviour. First of all it opens a new instance of Google Chrome. Nothing to do with Outlook at at all. It then crashes saying;
Cannot locate resource 'addressbook/someone#test.com'
It's almost as if this event is actually being handled elsewhere, but I am lamost certain it isn't. Has anyone experienced this before?
All that your solution does is tells windows to try to start a new process using the provided string.
You need to specify that you want it to use outlook.
Add the Microsoft.Office.Interop.Outlook reference to your project (make sure it's the correct version)
Then try something like this:
public static void OnEmailHyperlinkClick(object sender, RoutedEventArgs e)
{
try
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
MailItem msg = (MailItem)oApp.CreateItem(OlItemType.olMailItem);
msg.Subject = "My subject";
msg.Body = "My Message Body";
Recipients recipients = (Recipients)msg.Recipients;
Recipient recipient = (Recipient)recipients.Add("someone#test.com");
recipient.Resolve();
msg.Display(); // If you want to have the email displayed for the user to send
// Otherwise
msg.Send();
recipient = null;
recipients = null;
msg = null;
oApp = null;
}
catch (Exception ex)
{
}
}

C# send email with Outlook - No attachment in Outbox

I have a program that is using Outlook to send messages with attachments. It is working ok, sending emails with attachments but in outbox there is no attachment in the message. When somebody receive the message the attachment is visible but in outbox not.
Here is some code:
Outlook.MailItem mail = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mail.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;
int iAttachType = (int)Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue;
mail.Attachments.Add(Application.StartupPath+"/"+attachment, iAttachType, null, attachment);
mail.To = email;
mail.Subject = "Something";
mail.Body = "Some body";
mail.Send();
Before this I use:
private Outlook.Application outlookApp;
private Outlook._NameSpace outlookNameSpace;
private Outlook.MAPIFolder outbox;
and
outlookApp = new Outlook.Application();
outlookNameSpace = outlookApp.GetNamespace("MAPI");
outlookNameSpace.Logon(null, null, false, false);
outbox = outlookNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderOutbox);
My outlook program is connected with Microsoft Exchange Serwer. When I was using an application written in C++ it saved attachment in messages in outbox.
Thx for help!
You could be working with an old version of the outlook item.
This can happen if you keep references to your mail items, rec-patterns, inspectors and some other types [that I now forgot] longer than you need them.
Your reference will often point to the old version of the item and keeping it can also prevent you from getting a reference to the updated one (the one with the attachment), even when events (Folder.BeforeItemMove) are triggered.
Also, have you tried if mail.Save() would do anything for you?
This is what I use as soon as I am done with an item.
public static void NullAndRelease(object o)
{
if (o == null) {
return;
}
try {
int releaseResult = 0;
do {
releaseResult = System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
} while (releaseResult >= 0);
} catch {
} finally {
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
The catch has no message and is not important in my case. It is there if someone would pass in a reference that leads to something other than a com object. You can also try FinalReleaseComObject(o).

How to open Outlook new mail window c#

I'm looking for a way to open a New mail in Outlook window.
I need programically fill: from, to, subject, body information, but leave this new mail window open so user can verify content / add something then send as normal Outlook msg.
Found that:
Process.Start(String.Format(
"mailto:{0}?subject={1}&cc={2}&bcc={3}&body={4}",
address, subject, cc, bcc, body))
But there is no "From" option (my users have more than one mailbox...)
Any advice(s) ?
I've finally resolved the issue.
Here is piece of code resolving my problem (using Outlook interops)
Outlook.Application oApp = new Outlook.Application ();
Outlook._MailItem oMailItem = (Outlook._MailItem)oApp.CreateItem ( Outlook.OlItemType.olMailItem );
oMailItem.To = address;
// body, bcc etc...
oMailItem.Display ( true );
Here is what i have tried. It's working as expected.
This application Adding Recipients, adding cc and adding subject and opening a new mail window.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using Outlook = Microsoft.Office.Interop.Outlook;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ButtonSendMail_Click(object sender, EventArgs e)
{
try
{
List<string> lstAllRecipients = new List<string>();
//Below is hardcoded - can be replaced with db data
lstAllRecipients.Add("sanjeev.kumar#testmail.com");
lstAllRecipients.Add("chandan.kumarpanda#testmail.com");
Outlook.Application outlookApp = new Outlook.Application();
Outlook._MailItem oMailItem = (Outlook._MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Inspector oInspector = oMailItem.GetInspector;
// Thread.Sleep(10000);
// Recipient
Outlook.Recipients oRecips = (Outlook.Recipients)oMailItem.Recipients;
foreach (String recipient in lstAllRecipients)
{
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(recipient);
oRecip.Resolve();
}
//Add CC
Outlook.Recipient oCCRecip = oRecips.Add("THIYAGARAJAN.DURAIRAJAN#testmail.com");
oCCRecip.Type = (int)Outlook.OlMailRecipientType.olCC;
oCCRecip.Resolve();
//Add Subject
oMailItem.Subject = "Test Mail";
// body, bcc etc...
//Display the mailbox
oMailItem.Display(true);
}
catch (Exception objEx)
{
Response.Write(objEx.ToString());
}
}
}
You can't do this with mailto. Either your client will have to select the account they are sending from, which defaults to their default account or you will have to provide a mail form and set the headers when you send the e-mail.

Categories