How I can to move emails from inbox to some folder, for example folder "test"
Pop3Client client = new Pop3Client()
client contains method to get email in html, xml, etc. also delete email or delete all emails, but I need to move some email to another folder, it is possible ?
OpenPop implements the POP3 protocol. This protocol is old, and does not know about such things as folders. Therefore, the OpenPop implementation cannot handle folders as well.
If you need to use folders, consider using some IMAP client instead. IMAP is a newer and more modern protocol.
As J. Steen has pointed out. No, you can't with OpenPop.
Just encase you still want to do it and it wasn't a purely academic question. Taken from MSDN
How to: Programmatically Move Items in Outlook
This example moves unread e-mail messages from the Inbox to a folder named Test. The example only moves messages that have the word Test in the Subject field.
Applies to: The information in this topic applies to application-level projects for Outlook 2013 and Outlook 2010. For more information, see Features Available by Office Application and Project Type.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMail += new Microsoft.Office.Interop.Outlook.
ApplicationEvents_11_NewMailEventHandler
(ThisAddIn_NewMail);
}
private void ThisAddIn_NewMail()
{
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.
ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Items items = (Outlook.Items)inBox.Items;
Outlook.MailItem moveMail = null;
items.Restrict("[UnRead] = true");
Outlook.MAPIFolder destFolder = inBox.Folders["Test"];
foreach (object eMail in items)
{
try
{
moveMail = eMail as Outlook.MailItem;
if (moveMail != null)
{
string titleSubject = (string)moveMail.Subject;
if (titleSubject.IndexOf("Test") > 0)
{
moveMail.Move(destFolder);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Related
I have made an Outlook Add-In (Outlook 2013 and 2016 VSTO Add-In) for business purposes to save the email details to our database. The add-in is launched when a new email is composed, but closes when the email is sent.
The sent date of the email is only added after the email is moved to the Sent mailbox. Is there a way to use my current add-in (or another add-in) can be used to get that sent date after it has been closed without letting the user wait for it to be moved to the sent mailbox?
I know it can easily be done in VBA, but I want to preferably use an Add-in so that it can be easily loaded to all users with exchange server.
Wouldn't that date be today's date/time (Now) or something close to it?
Everything you can do in VBA you can do in a COM addin - subscribe to the Items.ItemAdd event on the Sent Items folder and retrieve the date when the event fires.
Thank you Dmitry for the reply. It set me on the right path. I used my existing VSTO add in to fire when a new item is added to the Sent mailbox. I did not know that when inserting this in the "ThisAddIn_Startup" method re-activates the add-in, which now makes sense.
I followed this example.
Here is my code:
Outlook.NameSpace outlookNameSpace;
Outlook.MAPIFolder Sent_items;
Outlook.Items items;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
outlookNameSpace = this.Application.GetNamespace("MAPI");
Sent_items = outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);
items = Sent_items.Items;
items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
}
void items_ItemAdd(object Item)
{
Outlook.MailItem mail = (Outlook.MailItem)Item;
string strMailItemNumber_filter = mail.UserProperties["MailItemNumber"].Value;
if ((Item != null) && (!string.IsNullOrWhiteSpace(strMailItemNumber_filter)))
{
if (mail.MessageClass == "IPM.Note" &&
mail.UserProperties["MailItemNumber"].Value.ToUpper().Contains(strMailItemNumber_filter.ToUpper())) //Instead of subject use other mail property
{
//Write 'Sent date' to DB
System.Windows.Forms.MessageBox.Show("Sent date is: "+ mail.SentOn.ToString()+ " MailNr = "+strMailItemNumber_filter);
}
}
}
I had to create a new mail user defined property to match the email I sent to find the correct email in the sent mailbox:
private void AddUserProperty(Outlook.MailItem mail)
{
Outlook.UserProperties mailUserProperties = null;
Outlook.UserProperty mailUserProperty = null;
try
{
mailUserProperties = mail.UserProperties;
mailUserProperty = mailUserProperties.Add("MailItemNrProperty", Outlook.OlUserPropertyType.olText, false, 1);
// Where 1 is OlFormatText (introduced in Outlook 2007)
mail.UserProperties["MailItemNumber"].Value = "Any value as string...";
mail.Save();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (mailUserProperty != null) Marshal.ReleaseComObject(mailUserProperty);
if (mailUserProperties != null) Marshal.ReleaseComObject(mailUserProperties);
}
}
I'm trying to write a C# console app that can programmatically update an Outlook distribution list (DL) in the Global Address List (GAL). I have permission to update this DL. I can do it interactively on my PC using Outlook, and I can do it in Perl code using Win32::NetAdmin::GroupAddUsers.
After adding a reference to COM library "Microsoft Outlook 14.0 Object Library", and then accessed via:
using Outlook = Microsoft.Office.Interop.Outlook;
I can successfully read from a DL, even recursing through DL's inside the "main" DL being searched. Here's that working code (critiques not needed for this piece):
private static List<Outlook.AddressEntry> GetMembers(string dl, bool recursive)
{
try
{
List<Outlook.AddressEntry> memberList = new List<Outlook.AddressEntry>();
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry dlEntry = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
if (dlEntry.Name == dl)
{
Outlook.AddressEntries members = dlEntry.Members;
foreach (Outlook.AddressEntry member in members)
{
if (recursive && (member.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeDistributionListAddressEntry))
{
List<Outlook.AddressEntry> sublist = GetMembers(member.Name, true);
foreach (Outlook.AddressEntry submember in sublist)
{
memberList.Add(submember);
}
}
else {
memberList.Add(member);
}
}
}
else
{
Console.WriteLine("Could not find an exact match for '" + dl + "'.");
Console.WriteLine("Closest match was '" + dlEntry.Name +"'.");
}
return memberList;
}
catch
{
// This mostly fails if running on a PC without Outlook.
// Return a null, and require the calling code to handle it properl
// (or that code will get a null-reference excception).
return null;
}
}
I can use the output of that to examine the members closely, so I think I understand the DL/member objects a bit.
But, the following code will NOT add a member to a DL:
private static void AddMembers(string dl)
{
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry ae = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
try {
ae.Members.Add("EX", "Tuttle, James", "/o=EMC/ou=North America/cn=Recipients/cn=tuttlj");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
ae.Update();
}
The arguments to Members.Add() are defined here, and the values shown in my code come exactly from examining my own Member object from another DL.
The exception displayed is simply "The bookmark is not valid." A similar question was asked before, but the solution was to use P/Invoke or LDAP. I really have no idea how to use P/Invoke (strictly a C# and Perl programmer, not a Windows/C/C++ programmer), and I don't have access to the LDAP server, so I really want to get this working through the Microsoft.Office.Interop.Outlook objects.
Any help is GREATLY appreciated!
After experimenting with several different .NET objects, using System.DirectorServices.AccountManagement as posted in Adding and removing users from Active Directory groups in .NET is what finally code this working for me. Closing out my own question.
I am working on a client that access an Exchange Web Service via a web reference. (not the Managed API). This is the first time I'm worked with EWS so I hope its just a simple mistake that I overlooked.
I have a method called MoveItem that is supposed to take email message and move it from the Inbox to destinationFolder. When I run this code, the item does disappear from the Inbox however it never shows up in the destination folder. I've spent a couple of days looking at examples online and I've also not been able to find anyone else that has had a similar issue. Can anyone tell me what I am doing wrong? Thanks in advance
Scott
static void MoveItem(ExchangeServiceBinding esb, BaseFolderType destinationFolder, MessageType msg)
{
ItemIdType[] items = new ItemIdType[1] { (ItemIdType)msg.ItemId };
BaseFolderIdType destFolder = destinationFolder.FolderId;
MoveItemType request = new MoveItemType();
request.ItemIds = items;
request.ToFolderId = new TargetFolderIdType();
request.ToFolderId.Item = destFolder;
try
{
MoveItemResponseType response = esb.MoveItem(request);
ArrayOfResponseMessagesType aormt = response.ResponseMessages;
ResponseMessageType[] rmta = aormt.Items;
foreach (ResponseMessageType rmt in rmta)
{
if (rmt.ResponseClass == ResponseClassType.Error)
{
throw new Exception("Item move failed.");
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Definitely not an expert here, but this is the following code I used to grab an item and move it into a folder:
Folder rootfolder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot);
rootfolder.Load();
foreach (Folder folder in rootfolder.FindFolders(new FolderView(100)))
{
// Finds the emails in a certain folder, in this case the Junk Email
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.JunkEmail, new ItemView(10));
// Enter your destination folder name below this:
if (folder.DisplayName == "Example")
{
// Stores the Folder ID in a variable
var fid = folder.Id;
Console.WriteLine(fid);
foreach (Item item in findResults.Items)
{
// Load the email, move it to the specified folder
item.Load();
item.Move(fid);
}
}
}
One thing about the EWS is that when moving to a folder, the ID of the folder is key. In this example, I first find the folders in the inbox, then access the messages. Therefore, any code regarding the individual message would go after the folders have been found.
I have same problem. The moved message doesn't exists in folder (outlook.com) but can be retrieved via APIs with new assigned id.
Outlook.com can find it in search with an error while loading message body:
Error: Your request can't be completed right now. Please try again later.
Is there any way to get all mail from an specific Folder into my Application?
Check this link. Introduction to Outlook Programming will explain things more clearly.
You could loop through the mailitems. Sample code
using System.Runtime.InteropServices;
using OutLook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
OutLook.Application oApp;
OutLook._NameSpace oNS;
OutLook.MAPIFolder oFolder;
OutLook._Explorer oExp;
oApp = new OutLook.Application();
oNS = (OutLook._NameSpace)oApp.GetNamespace("MAPI");
oFolder = oNS.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderInbox);
oExp = oFolder.GetExplorer(false);
oNS.Logon(Missing.Value, Missing.Value, false, true);
OutLook.Items items = oFolder.Items;
foreach (OutLook.MailItem mail in items)
{
if (mail.UnRead == true)
{
}
}
Edit:
Reference other folders
oFolder.Folders["Foldername"]
OutLook Code
Common Outlook tasks
Looping through all items in a folder is a terrible idea, especially if you are working against an online Exchange store. Items.Find/FindNext or Items.Restrict is the way to go.
Find/FindNext:
OutLook.Items items = oFolder.Items;
OutLook.MailItem mail = items.Find("[Unread] = true");
while (mail != null)
{
MessageBox.Show(mail.Subject);
mail = items.FindNext();
}
Items.Restrict:
OutLook.Items items = oFolder.Items.Restict("[Unread] = true")
foreach (OutLook.MailItem mail in items)
{
MessageBox.Show(mail.Subject);
}
There's some examples of accessing Outlook folders here, one of which deals specifically with unread mail.
Edit: There's a KB article specifically about accessing folders from C#, Programming samples that can reference items and folders in Outlook by using Visual C# .NET
To open another user's folder, use GetSharedDefaultFolder
foreach (Object Unreadmail in folderItems)
{
if ((Unreadmail as Outlook.MailItem) != null && (Unreadmail as Outlook.MailItem).UnRead == true)
{
//DO Your action Here
}
}
I have experienced "COM_object" exception error with above solutions, More info please refer here
I wanted to save Outlook mails in to msg format along with the attachment through C#.
I tried the following code
using Outlook = Microsoft.Office.Interop.Outlook;
private void button1_Click(object sender, EventArgs e)
{
Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Outlook.NameSpace ns = app.GetNamespace("MAPI");
Outlook.MAPIFolder inbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
foreach (Outlook.MailItem item in inbox.Items)
{
item.SaveAs(finename, Outlook.OlSaveAsType.olMSG);
}
}
It could save the mail as msg but the attachment part was removed. SaveAs method had no other overloads alos... :(
If i try to save a message from outlook it saves the message along with the attachment embedded in it. Any idea how this can be achieved..?
I am using .Net Framework 3.5 and Outolook 2007
What are you using as a filename? does it end with .msg?
I do something like this and it works as you describe you want it too:
Outlook.MailItem msg;
foreach (object obj in f.Mapi.Items)
{
try
{
msg = obj as Outlook.MailItem;
// ... set file name using message attributes
// string fullPath = "something" + ".msg"
msg.SaveAs(fullPath, Outlook.OlSaveAsType.olMSG);
}
}
The reason I'm so curious in your case is that I am wondering how I can reproduce what you are doing: saving the mail item with out saving the attachments?
I believe that you will have to save them separately.
Use the Attachments property on the MailItem to get all the attachments. then loop through them and call SaveAsFile() for each of the attachments.
examples in below link are for basic, but it should work in C# as well
MailItem::Attachments
http://msdn.microsoft.com/en-us/library/bb207129.aspx
Attachment::SaveAsFile
http://msdn.microsoft.com/en-us/library/bb219926.aspx