Outlook AutoComplete Email List - c#

I want extract list all autocomplete email addresses in outlook 2016 (office 365) using C#.
I am using following code;
NameSpace olNS = this.Application.GetNamespace("MAPI");
MAPIFolder inboxFolder = olNS.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
StorageItem storage = inboxFolder.GetStorage("IPM.Configuration.Autocomplete", OlStorageIdentifierType.olIdentifyByEntryID);
PropertyAccessor propertyAcc = storage.PropertyAccessor;
byte[] bytes = propertyAcc.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7C090102");
When I execute above code I get the following error
Cannot create StorageItem in this folder. Either the folder is read-only, or a storage item is not allowed in this folder.
Please help in this regard
Thanks

You need to pass OlStorageIdentifierType.olIdentifyByMessageClass instead of OlStorageIdentifierType.olIdentifyByEntryID:
NameSpace olNS = this.Application.GetNamespace("MAPI");
MAPIFolder inboxFolder = olNS.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
StorageItem storage = inboxFolder.GetStorage("IPM.Configuration.Autocomplete", OlStorageIdentifierType.olIdentifyByMessageClass);
PropertyAccessor propertyAcc = storage.PropertyAccessor;
byte[] bytes = (byte[])propertyAcc.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7C090102");
The code listed above works like a charm on my machine!
However, be aware, the GetStorage returns an error if the store type of the folder is not supported. The following stores return an error when GetStorage is called:
Hotmail store
Internet Message Access Protocol (IMAP) stores
Delegate stores
Public folder stores

Related

How to check email for file using c#?

I receive an email with an excel file every week. I know there are probably better ways to accomplish my goal, but would it be possible to have a script task in SSIS that can open email, look for a specific file name as an attachment and then copy that file to another location?
Here is the scenario. This excel file is important for my team to have in a SQL database, and the provider of the excel source is only willing to email this excel file to us once per week. I then check my email, copy the file to a location where an SSIS dataflow task can then pick it up and insert it into a SQL table. I would like to automate this. So if my original approach is not doable, how else could this be automated? Aside from using a shared network location. Assume the excel file can ONLY come from the email. Using outlook/office 365, SSIS, SSMS, I have DBO access, and can use c#.
I'll admit that I'm ignorant on the email. If there is a procedure that the email client can actually execute to accomplish this, then I'd be all ears!
EDIT: I also have access to a network drive as I realize saving to my local machine may be impossible.
Simple Answer Yes it is Possible.
I had written a console program to process email on Office365 that I was also interfacing with SQL, so it definitely can be done. It isn't necessarily the easiest thing in the world but it is not too hard either.
You can use the Exchange Web Services (EWS) Managed API
Article on stating it is possible and the API documentation
https://msdn.microsoft.com/en-us/library/office/dd877012(v=exchg.150).aspx
Github location where you can find the API (note this link is directly form Microsoft's Site)
https://github.com/officedev/ews-managed-api
Link on how to reference the assembly which contains the second link above:
https://msdn.microsoft.com/en-us/library/office/dn528373(v=exchg.150).aspx
Create and Connect to Service
string emailAddress = 'YourEmail#Domain.com';
ExchangeService exService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exService.Credentials = new WebCredentials(emailAddress,"password");
you can autodiscover or if you know the URL just set it so 1 of these lines
exService.AutodiscoverUrl(_emailAddress, delegate { return true; });
exService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
Find your Inbox & a Folder to Move the File To After Being Processed:
FolderView folderView = new FolderView(1);
folderView.PropertySet = new PropertySet(BasePropertySet.IdOnly);
folderView.PropertySet.Add(FolderSchema.DisplayName);
folderView.Traversal = FolderTraversal.Deep;
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "ProcessedFolderName");
Folder Inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
FindFoldersResults folderResults = Inbox.FindFolders(searchFilter, folderView);
FolderId processedFolderId = folderResults.Folders[0].Id;
Find Messages That meet your criteria:
List<SearchFilter> searchFilterCollection = new List<SearchFilter();
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,"Words in Subject"));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(ItemSchema.HasAttachments,true));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.From,new EmailAddress("From#SendersDomain.com")));
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,searchFilterCollection);
ItemView view = new ItemView(50, 0, OffsetBasePoint.Beginning);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived, ItemSchema.Attachments);
view.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox,searchFilter,view);
Process the results and save the attachments when done move the message to another folder so you don't keep importing the same one.
foreach (Item i in findResults.Items)
{
foreach(FileAttachment attachment in i.Attachments)
{
attachment.Load(#"\\FilePathDirectory\" + attachment.FileName);
}
i.Move(processedFolderId);
}
you can expand the solution by testing if you get no results sending yourself an error message or throwing an error for SSIS to pickup and fail the job. It is likely that you will overwrite the file multiple times if you have multiple messages to process so you may consider adding something unique in the file name instead of just using the same one but that will present other challenges in SSIS as well.
anyway, its a start hope it helps.

delete imap folder using Mailkit

I am using the Mailkit for .net and am having trouble to delete a IMAP-folder that I created by Code. This is my sample code:
Created the folder like this:
var personal = Program.Client.GetFolder (Program.Client.PersonalNamespaces[0]);
var mailkit = personal.Create("mailkit", false);
var archive = mailkit.Create("archive", true);
var flagged = mailkit.Create("flagged", true);
...
Tried to delete the Folder again like this:
var temp = Program.Client.GetFolder("mailkit");
temp.Delete();
Get an FolderNotFoundException, but the folder is still there?
Need a little help or tip how to do ...
(Sorry for this bad english :))
Program.Client.GetFolder("mailkit"); is throwing a FolderNotFoundException because the folder doesn't exist. You need to provide the full path of the folder to ImapClient.GetFolder(string path), but instead you have only provided the folder's name.
Here's how to get the "mailkit" folder:
var personal = Program.Client.GetFolder (Program.Client.PersonalNamespaces[0]);
var mailkit = personal.GetSubfolder ("mailkit");

how to access my yahoo or gmail account in outlook (c#)?

I have 3 data files:
Outlook data file (is empty)
Gmail data file (from my gmail pop3)
Yahoo data file (from my yahoo imap)
I can access the Outlook data file inbox (which is always empty, I don't know how to automatically move from my google and yahoo account to my outlook data file) with
this code:
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.
ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
I have 2 questions:
How can I make my gmail and yahoo account automatically move to my outlook data file?
How to code to access my inbox in my gmail and yahoo account?
I have tried this function to make return to my MAPIFolder:
public Outlook.MAPIFolder GetInbox(string userName)
{
Outlook.Application oOutlook = new Outlook.Application();
Outlook.NameSpace oNs = oOutlook.GetNamespace("MAPI");
Outlook.Recipient oRep = oNs.CreateRecipient(userName);
Outlook.MAPIFolder inbox = oNs.GetSharedDefaultFolder(oRep, Outlook.OlDefaultFolders.olFolderInbox);
return inbox;
}
But it didn't work. help me pleaseee..
I'm not sure I understand your first question, would you like to join all the data files into the main outlook data file?
About your second question, Outlook data files are represented by stores in the API, and if you call GetDefaultFolder on the Session object, you'll always end up with getting the default store's default folder (Inbox of your Outlook data file).
You can list all the store files and use GetDefaultFolder on them to retrieve the inbox folders for each store/data file:
Outlook.Stores stores = this.Appliction.Session.Stores;
foreach( Store store in stores )
{
Outlook.Folder inboxOfStore = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
//Do stuff with your inbox folder.. Check store properties for infomation on which data file this store represents
}
See documentation for more information:
http://msdn.microsoft.com/en-us/library/office/bb176405%28v=office.12%29.aspx

Open Specific MailItem in Outlook from C#

I want to open a specific email in Outlook from my C# winforms application.
At the moment I have got the following code:
//...Get Folder & Entry ID for last Email in Sent Box
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 folderEntryID = mySentBox.EntryID;
string folderStoreID = mySentBox.StoreID;
string mailAddressee = myMail.To;
MessageBox.Show(mailAddressee);
//...Attempt to Open that Email at a later date
Outlook.MAPIFolder getFolder = (Outlook.MAPIFolder)mapiNameSpace.GetFolderFromID(folderEntryID, folderStoreID);
Outlook.MailItem getItem = (Outlook.MailItem)getFolder.Items.Find("[EntryID] = " + guid);
getItem.Display();
The first an second parts of the code will be run at different times, although they are in the same Method for testing at the moment.
The first part obtains the relevant IDs for the mst recently sent email from Outlook. This part seems to work fine as evidence my the Messagebox I've built in.
The second part however is not working and I'm struggling to find the right code to access and open that specific mailItem having obtained its ID and folder location in the first part.
Anyone able to complete this little project for me please.
Done it at last by replacing the following lines of code . . .
Outlook.MAPIFolder getFolder = (Outlook.MAPIFolder)mapiNameSpace.GetFolderFromID(folderEntryID, folderStoreID);
Outlook.MailItem getItem = (Outlook.MailItem)getFolder.Items.Find("[EntryID] = " + guid);
with this . . .
Outlook.MailItem getItem = (Outlook.MailItem)mapiNameSpace.GetItemFromID(guid, folderStoreID);
You can not use EntryId with the _Items.Find method. The MSDN reference is here.
There is also a remark which could be interesting for your project:
"The Entry ID changes when an item is moved into another store, for
example, from your Inbox to a Microsoft Exchange Server public folder,
or from one Personal Folders (.pst) file to another .pst file.
Solutions should not depend on the EntryID property to be unique
unless items will not be moved."
MailItem.EntryID Property (Outlook).

Using Outlook API to get to a specific folder

I'm trying to write some C# code to get to a specific folder in an Outlook mailbox. I have the following code:
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
Outlook.Recipient oRecip = oNS.CreateRecipient("AccountNameHere");
oRecip.Resolve();
if (oRecip.Resolved)
{
oInbox = oNS.GetSharedDefaultFolder(oRecip, Outlook.OlDefaultFolders.olFolderInbox);
oInboxMsgs = oInbox.Items;
ItemCount = oInboxMsgs.Count;
Console.Writeline("There are {0] items.", ItemCount.ToString())
}
This will get me to to the "Inbox" folder. I'm trying to get to a folder at the same level as the Inbox folder. I believe I need to use GetFolderFromID instead of GetSharedDefaultFolder, but I don't understand how to use it. Is there a way to iterate through all the top level folders? How might I determine the EntryID and StoreID of the folder?
Thanks!
You can use the Folders collection member of the Outlook.NameSpace object. That way you can iterate through the collection and find your folder by it's name. In case you still want to use GetFolderFromID, you can use OutlookSpy tool to get the EntryID and StoreID values.

Categories

Resources