PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2024 → EWS extract mail to .eml
EWS extract mail to .eml
Iniciado por guest, 04,may. 2017 12:19 - 11 respuestas
Publicado el 04,mayo 2017 - 12:19
Hi guys.

I am using Exchange WebServices to access multiple mailboxes on an Exchange server. Because I want my application to run as a system service, I cannot - and don't want - to use the built in functions as it relies on outlook and I don't want to create a million Outlook profiles... This solution also has the benefit of running from a non-domain connected computer. If it was possible to get working thoroughly, it could be used as the basis for an archival tool or a way to backup multiple Exchange online accounts (o365)

I can log in just fine, list folder contents, load individual messages, save attachments etc. All good.
However, What I really want to do is to save the messages as .EML files. According to the EWS API this can only be done by saving the MIMECONTENT of the message as a whole.

Here is my code (Most of which works great), hope fully someone will find this useful
The bit that doesn't work is the saving of the mimecontent near the end.

If anyone has done this successfully, I'd be delighted if you could share

Cheers, Bosh
ServiceEWS is an ExchangeService(ExchangeVersion.Exchange2013,TimeZoneInfo.Utc) ServiceEWS.Credentials = new WebCredentials("login","pw","WDomain") //Note. Wdomain is the NT style domain name, not the public domain name ServiceEWS.Url = new Uri("https://mail.yourdomain.com/EWS/Exchange.asmx"); //Test read of ten messages in Inbox clInbox is a Folder(ServiceEWS) clInbox <- Folder.Bind(ServiceEWS,WellKnownFolderName.Inbox) clFindresults is a 'FindItemsResults<Microsoft.Exchange.WebServices.Data.Item>' clFindresults <- ServiceEWS.FindItems(WellKnownFolderName.Inbox,new ItemView(10)) clMail is an EmailMessage(ServiceEWS) FOR ALL i OF clFindresults.Items xs is an 'Collection<Microsoft.Exchange.WebServices.Data.PropertyDefinitionBase>' xs.add(ItemSchema.Attachments) clMail <- EmailMessage.Bind(ServiceEWS,i.id, new PropertySet(BasePropertySet.IdOnly, xs)) clMail.Load() Trace(clMail.Subject) END bMoreItems is a boolean = True ipagesize is int = 50 IOffset is int nIIter is int nIDspCnt is int //Search for subfolders of Inbox vi is a FolderView = Null Scfilt is a SearchFilter = Null Scfilt <- new SearchFilter.IsGreaterThan(FolderSchema.TotalCount, 0); vi <- new FolderView(ipagesize,IOffset) vi.PropertySet = new PropertySet(BasePropertySet.IdOnly) vi.PropertySet.Add(FolderSchema.DisplayName) vi.PropertySet.Add(FolderSchema.Id) vi.PropertySet.add(FolderSchema.FolderClass) vi.Traversal = FolderTraversal.Deep Trace("The " + clInbox.DisplayName + " has " + clInbox.ChildFolderCount + " child folders."); // Now do something with the folder, such as display each child folder's name and ID. clFoldersFound is a FindFoldersResults clFolder is a Folder(ServiceEWS) sFolder is string clBMimeContent is a MimeContent() nFile is int clMail2 is an EmailMessage(ServiceEWS) bufMsg is Buffer nLen is int sFname is string WHEN EXCEPTION IN WHILE bMoreItems = True clFoldersFound <- ServiceEWS.FindFolders(WellKnownFolderName.Inbox,Scfilt,vi) bMoreItems = clFoldersFound.MoreAvailable IF bMoreItems = True THEN vi.Offset = vi.Offset + ipagesize END nIIter = 0 nIDspCnt = clFoldersFound.Folders.Count FOR ALL it OF clFoldersFound.Folders clFolder.DisplayName = it.displayname sFolder = Upper(clFolder.displayname) SWITCH Left(sFolder,3) CASE "LON", "HOU", "PER", "NEW", "SGP", "RSA", "BRL" Trace(it.DisplayName) clFindresults2 is a 'FindItemsResults<Microsoft.Exchange.WebServices.Data.Item>' clFindresults2 <- ServiceEWS.FindItems(it.id,new ItemView(10)) Trace("ok") //Get Items FOR ALL i OF clFindresults2.Items sFname = "\ est_" + TimeSys() + "\.eml" xs2 is an 'Collection<Microsoft.Exchange.WebServices.Data.PropertyDefinitionBase>' xs2.add(ItemSchema.MimeContent) xs2.add(ItemSchema.TextBody) clMail2 <- EmailMessage.Bind(ServiceEWS,i.id, new PropertySet(BasePropertySet.IdOnly,xs2)) fDelete(SysDir(srMyDocuments) + sFname) nFile = fOpen(SysDir(srMyDocuments) + sFname,foCreateIfNotExist+foUnicode) //Crashes here :( fWrite(nFile,clMail2.MimeContent.content) fClose(nFile) Trace("woop") END OTHER CASE Trace("no match - " + it.DisplayName) END END END DO END
Publicado el 04,mayo 2017 - 14:41
Hi

what is the error message ?
Why not do a fsauvetext?

Best regards
Publicado el 04,mayo 2017 - 15:21
Hi Fabrice

Actually the code I posted is slightly incorrect. I am loading each message in the last loop with clmail2.Load().

I am using the .Net assembly Microsoft.Exchange.Webservices so I am receiving no error when I call errorinfo(errfulldetails)

:(
Publicado el 04,mayo 2017 - 15:31
Hi Fabrice, I tried fsavetext and it reports 'no compatible syntax' :(
Publicado el 05,mayo 2017 - 15:36
Hi

so what is the incorrect syntax you are using?

Best regards
Publicado el 05,mayo 2017 - 18:49
Hi Fabrice

I have tried

sFname = "\ est_" + TimeSys() + "\.eml"
fSaveText(SysDir(srMyDocuments) + sFname,clMail2.MimeContent)

and
sFname = "\ est_" + TimeSys() + "\.eml"
fSaveText(SysDir(srMyDocuments) + sFname,clMail2.MimeContent.Content)

Windev not happy with either :0

Cheers

Bob
Publicado el 07,mayo 2017 - 11:08
Hi,

Perhaps you should try sFname = ".\ est_" + TimeSys() + "\.eml" as you now are trying to save a .eml file in the \ est_" + TimeSys() + "\" folder that probably do not exist.

cheers
Tor-Bjarne
Publicado el 07,mayo 2017 - 14:24
Hi Tor-Bjarne

Thanks for the suggestion but the problem is much simpler. The Windev editor itself is complaining about the syntax used (Which is fine). I guess it's clever enough to figure out that the object being saved is not a text object.

My original code mirrors the documented c# code (Still working on it...)
nFile = fOpen(SysDir(srMyDocuments) + sFname,foCreateIfNotExist+foUnicode)
//Crashes here :(
fWrite(nFile,clMail2.MimeContent.content)
fClose(nFile)

Cheers

Bob
Publicado el 08,mayo 2017 - 01:02
So after all you had a compilation error by windev saying that mimecontent is not a string...

Had you say it first, and would save us a lot time.

I checked on google and MimeContent is a class with six methods. One of them being ToString

https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.mimecontent_members(v=exchg.80).aspx

so use MimeContent.ToString

Regards,
José Antonio.
Publicado el 08,mayo 2017 - 09:42
Hi Jose,

Thanks for your help. It works perfectly!
Sorry, I didn't see that method in the documentation :0

Cheers

Bosh
Publicado el 08,mayo 2017 - 11:19
Hi Bosh,

Just FYI:
In .Net (C#) any reference type derives from the base Object Class which has the ToString method.
So, all types in .Net have a ToString method (with many different signatures for about any purpose).
https://msdn.microsoft.com/en-us/library/system.object.tostring(v=vs.110)

Cheers,

Peter
Publicado el 08,mayo 2017 - 15:46
Hi Peter,

Thanks for the info. I try to avoid .NET as much as possible but this API is too good to miss! :)

So many possibilities.

Backup for office365 mail anyone? Easy!
Integrate email into CRM etc...

Thanks for your help guys

Cheers

Bosh