how to copy mailitem in outlook c# - c#

I am writing an outlook add-in,
and I need when receiving an email, it goes to default inbox folder as normal, but it make a copy of that incoming email and put it into another folder(say Junk folder as example).
but I encounter the exception "Cannot move the items." all the time when i move the copy of the email. any ideas?
private void items_ItemAdd(object Item)
{
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
// the incoming email
Outlook.MailItem mail = (Outlook.MailItem)Item;
//make a copy of it but error occurs
Outlook.MailItem cItem = mail.copy();
//
cItem = (Outlook.MailItem)cItem.Move((Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderJunk));

You are in the ItemAdd event handler. Try to store the item's entry id in a variable or a list and start a timer (use the one from the Forms namespace). When the time fires, you will be out of the event handler and should be able to call MailItem.Move.

Related

Open Specific MailItem in Outlook from C# via Mail.EntryID

Similar to this question,
Open Specific MailItem in Outlook from C# , In a C# VSTO application I'm trying to open an email in a new outlook window/inspector using the method GetFolderFromID and passing it's EntryID and StoreID.
Full code below:
Outlook.Application myApp = new Outlook.ApplicationClass();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Outlook.MAPIFolder mySentBox = mapiNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Outlook.MailItem myMail = ((Outlook.MailItem)mySentBox.Items[1]);
string guid = myMail.EntryID;
string folderStoreID = mySentBox.StoreID;
Outlook.MailItem getItem = (Outlook.MailItem)mapiNameSpace.GetItemFromID(guid, folderStoreID);
getItem.Display();
The below code only opens up the requested email in a new window when the email is already selected within outlook.
getItem.Display();
If not selected, the following error returns.
System.Runtime.InteropServices.ComException: 'A dialog box is open. Close it and try again'.
I've also attempted adding a new inspector & activating/displaying the email object via it with no success.
Kind regards
The error simply means a dialog box is open. Make sure there are no modal windows displayed and make sure you ever call MailItem.Display(true) to display items modally.

Issues reading unread mails in Outlook

I am trying to develop an add-in for Outlook. In that I want remove attachment when a new mail is received.
So I call my function on the NewMailEx event. It is working fine. In that function I try to find unread mails in the Outlook inbox. From those I remove the attachments.
My problem is: when I open Outlook, the first mail I received is not showing in the inbox (not in outlook c# code), so I can't remove the attachment from that mail.
From the second mail (after the first mail), I can get the received mail, so I can remove the attachments.
Whenever I close and reopen Outlook, the first mail I receive gives this problem.
At the first mail received there is no unread mail.
private void Application_NewMailEx(object Item)
{
string senderEmailid = string.Empty;
outlookNameSpace = this.Application.GetNamespace("MAPI");
Outlook.Application myApp = new Outlook.Application();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Outlook.MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Attachments attachments;
int test = myInbox.Items.Count;
Microsoft.Office.Interop.Outlook.Recipients recipients = ((Outlook.MailItem)myInbox.Items[test]).Recipients;
Outlook.Items unreadItems = myInbox.Items.Restrict("[Unread]=true");
if (unreadItems.Count > 0)
{
foreach (Outlook.MailItem mail in unreadItems)
{
Outlook.Recipient recip;
Outlook.ExchangeUser exUser;
string sAddress;
if (mail.SenderEmailType.ToLower() == "ex")
{
recip = Globals.ThisAddIn.Application.GetNamespace("MAPI").CreateRecipient(mail.SenderEmailAddress);
exUser = recip.AddressEntry.GetExchangeUser();
sAddress = exUser.PrimarySmtpAddress;
}
else
{
sAddress = mail.SenderEmailAddress.Replace("'", "");
}
string[] emailAddressPart = sAddress.Split('#');
string strSenderDomain = emailAddressPart[1];
if (lstDomain.Any(item => item.Contains(strSenderDomain)))
{
attachments = mail.Attachments;
int nAttachmentCount = mail.Attachments.Count;
if (nAttachmentCount > 0)
{
int j = nAttachmentCount;
for (int i = 1; i <= nAttachmentCount; i++)
{
mail.Attachments[j].Delete();
j--;
}
}
}
}
}
}
The NewMailEx event of the Application class is not the best place for searching unread emails. 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 alternative way is to handle the ItemAdd event of the Items class.
Instead, you can wait until Outlook finishes synchronizing items and run your code for searching unread emails. The SyncEnd event of the SyncObject class is fired immediately after Microsoft Outlook finishes synchronizing a user’s folders using the specified Send/Receive group.
Also you may consider handling the Startup or MAPILogonComplete events. But they are fired before the synchronization is completed. Consider using a timer to run the procedure a bit after Outlook is started.
You can read about possible ways of handling incoming emails in the following series of articles:
Outlook NewMail event unleashed: the challenge (NewMail, NewMailEx, ItemAdd)
Outlook NewMail event: solution options
Outlook NewMail event and Extended MAPI: C# example
Outlook NewMail unleashed: writing a working solution (C# example)
Also I'd recommend breaking the chain of calls and delaclaring each property or method call on a separate line of code. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server. If you do not release these objects in a timely manner, you can reach the limit imposed by Exchange on the maximum number of items opened at any one time. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article in MSDN.
There is nothing you can do about that. From the documentation on NewMailEx:
Also, the event will fire only if Outlook is running. In other words, it will not fire for the new items that are received in the Inbox when Outlook was not open.
That means you have to manually call your method to walk down all the unread emails when opening Outlook.

Outlook Add-In, right Eventhandler

I try to build a Add-In that saves Attachments form a Mail with a specific Subject.
Till now that works fine, but i think that im using the wrong Eventhandler for my needs.
It should start if a new Mail comes in, and then check the whole Inbox + the new mail.
atm im using Microsoft.Office.Interop.Outlook.ApplicationEvents_11_NewMailEventHandler()
so he just looking for the Inbox without the new item, because at that moment the new mail isnt part of the inbox
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMail += new Microsoft.Office.Interop.Outlook
.ApplicationEvents_11_NewMailEventHandler(ThisAddIn_NewMail);
}
What can i do instead ?
You can assume that the email will be unread, so you should be able to use Items.Find/FindNext to look for the unread messages. Or you can store the date of the last processed e-mail and, again, use Items.Find/FindNext to search for messages with CreationTime greater than some value.

Obtain Mail Item details from .MSG attachment

Is it possible to obtain Outlook Mail Item details by dragging and dropping a single attachment from a .MSG file onto a C# application? My application currently separates the contents of a .MSG when this is dropped onto my application, however I want to go a step further and obtain sender, date/time received etc from a single attachment that is part of the .msg. This is what I'm trying at the moment:
Outlook.Application myApp = new Outlook.Application();
object selectedItem = myApp.ActiveExplorer().Selection[1];
Outlook.MailItem item = selectedItem as Outlook.MailItem;
string sender = item.SenderName;
When I try to cast selectedItem as an Outlook.Mail Item nothing happens. Any help with this would be appreciated
Thanks
Chris
Since my initial post I have been looking at other ways in which to obtain the information that Im looking for as I have not been successful with the method above..
I have looked at the following article http://msdn.microsoft.com/en-us/library/aa219397(v=office.11).aspx and implented the code in a test project. I know initially I asked if I could obtain the msg details from the attachement, however if a user drags an attachment from the current open message then I was wondering if it were possible to obtain the message details from the ActiveExplorer method.
At the point where:
myOlSel.Item(x).SenderName & ";"
Outlook prompts me with " A program is trying to access email address..." but at this the message box hangs and I cannot select one of the options. After doing some further reading I understand why this is in place but is there anyway around it?
Thanks
Chris
Maybe the selectedItem is null because there actually is no selected item at index 1?
I have the follwowing at is is working (althou it's with an Appointment item)
Inspector activeInspector = this.OutlookApp.ActiveInspector() as Inspector;
object currentItem = activeInspector.CurrentItem;
if (currentItem != null && currentItem is AppointmentItem)
{
AppointmentItem appItem = currentItem as AppointmentItem;
}
Perhaps you should use Selection[0]?

How to Program Outlook 2007 Add-In with Multiple Mailboxes

I'm trying to figure how to write a simple add-in for Excel 2007, but one that only interacts with one of my mailboxes. Currently I have two email addresses coming into my outlook, each in a specific 'mailbox'. I was wondering, how would I specify a NewMail event for a specific mailbox?
Or, perhaps not as clean, but how could I write an if function that specifies which mailbox / email any new item is addressed to...
Hopefully this makes sense. Thanks
To catch new mail event, add this code to addin startup method:
this.Application.NewMailEx +=
new Outlook.ApplicationEvents_11_NewMailExEventHandler(Application_NewMailEx);
Then add method to handle NewMailEx event:
void Application_NewMailEx(string EntryID)
{
// get MailItem for this new mail
Outlook.Explorers explorers = this.Application.Explorers;
Outlook.MailItem newMail =
(Outlook.MailItem)explorers.Application.Session.GetItemFromID(EntryID, System.Reflection.Missing.Value);
// check SendUsingAccount to see if it came in mailbox we are interested in
if (newMail.SendUsingAccount.DisplayName == "your.name#your.domain.com")
{
// do whatever You like
}
}
Add using statement also:
using Outlook = Microsoft.Office.Interop.Outlook;

Categories