?
Solved

Windows service retrieve/send mails via Exchange server (without POP3).

Posted on 2006-03-21
8
Medium Priority
?
314 Views
Last Modified: 2012-06-27
Hi,

I need to adapt a service to retrieve/send mails via an Exchange server (without POP3 communication). In a test application I used components in the Servers, which seemed to work fine. While incorporating this in the service I came across this site: "The Outlook Object Model is unsuitable to run in a Windows service" (http://support.microsoft.com/?kbid=237913). So my question now is what is the best way to handle this. Just incorporate the components into my service or use another solution? Thanks.

Regards,
Wim.
0
Comment
Question by:ecomaster
8 Comments
 
LVL 32

Accepted Solution

by:
jhance earned 1000 total points
ID: 16246541
Exchange supports multiple methods of communicating with clients and POP3 is only one of them.  It also supports IMAP as well as MAPI which is the API that Outlook uses to communicate with Exchange.

0
 
LVL 2

Expert Comment

by:Hamlet10
ID: 16247001
Hi Wim,

I recently had the same issues. I was for security reasons not allowed to access the Exchange server using POP3. IMAP4, or WebDAV.

Instead I used CDO objects which works fine. The windows service I  have written takes emails tha arrive into the mail box are transfers the information to a SQL server.


I can include all of the code from the windows service if you would like.



Regards


Hamlet
0
 

Author Comment

by:ecomaster
ID: 16247284
Thanks Hamlet10, that would be a great help!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 2

Assisted Solution

by:Hamlet10
Hamlet10 earned 1000 total points
ID: 16247680
Wim,

Here is teh code I used as requested. It is a but messy but If you open it in VS the colour coding should clear things up slightly.

=============================================================


Imports Outlook = Microsoft.Office.Interop.Outlook
Imports System.Runtime.InteropServices


Public Class clsEmailRetriever
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Dim EmailLog As New EventLog

    Public Sub Main()

        Dim cdoSession As MAPI.Session
        Dim cdoFolder As MAPI.Folder
        Dim cdoField As MAPI.Field


        Dim strLabels As String
        Dim strLabelName As String
        Dim strAllLabels As String
        Dim strChar As String
        Dim j As Integer
        Dim Messages As MAPI.Messages
        Dim Message As MAPI.Message


        Dim sendMail As MAPI.Message

        ' create a new event log
        EmailLog.Source = "Email Log"



        Dim EntryID As String
        Dim StoreID As String
        Dim oldFolderEntryID As String
        Dim ForecastInValue As String
        Dim ForecastOutValue As String


        EntryID = Me.GetConfigSetting("EntryID")
        StoreID = Me.GetConfigSetting("StoreID")

        ForecastInValue = Me.GetConfigSetting("ForecastInValue")
        ForecastOutValue = Me.GetConfigSetting("ForecastOutValue")

        Dim i As Integer

        ' Create Outlook application.
        cdoSession = CreateObject("MAPI.Session")

        cdoSession.Logon("Forecast Data", , False, True)


        cdoFolder = cdoSession.GetFolder(EntryID, StoreID)


        Messages = cdoFolder.Messages()



        Dim Subject As String

        Dim m As Int32
        Dim Item As Integer

        Dim msgType As String = "Invalid"

        Dim Body As String
        For Each Message In cdoFolder.Messages()

            Try
                Subject = String.Empty
                Subject = Message.Subject


                msgType = String.Empty
                Body = String.Empty

                If Subject.IndexOf(ForecastOutValue) > 0 Then
                    msgType = "ForecastsOut"

                ElseIf Subject.IndexOf(ForecastInValue) > 0 Then
                    msgType = "ForecastsIn"

                End If

                Dim Data() As String
                Dim DataHeader() As String

                If msgType = "ForecastsIn" Then

                    Body = Message.Text

                    Body = Body.Replace(Chr(13) & Chr(10) & Chr(9), ",")
                    Body = Body.Replace(Chr(13) & Chr(10) & Chr(13) & Chr(10), "%")


                    Data = Body.Split("%")

                    DataHeader = Data(0).Split(" ")

                    Body = Data(1).Replace(Chr(9), "")

                    Body = Body.Replace("Notes,", ("Notes," & DataHeader(5) & " " & DataHeader(6)))
                    'Replace invalid characters here
                    'Replace
                    'Forecast Time,Windspeed (m/s),Direction (°N),Temperature (°C)
                    'with
                    'Forecast Time Windspeed (m/s),Direction (ºN),Temperature (ºC)
                    Body = Body.Replace("Direction (°N),Temperature (°C)", "Direction (ºN),Temperature (ºC)")
                    Body = Body.Replace(",Windspeed (m/s),", " Windspeed (m/s),")

                    Body = (Body & Chr(13) & Chr(10))

                    EmailLog.WriteEntry("Email Log", "Email Processed: " & Subject, EventLogEntryType.Information)
                    CreateFile(msgType, Body)
                    Message.Unread = False
                    Message.Update()
                    Message.MoveTo(oldFolderEntryID)

                ElseIf msgType = "ForecastsOut" Then
                    Body = Message.Text
                    Body = Body.Replace(Chr(13) & Chr(10) & "Windspeed", "Windspeed")
                    Body = Body.Replace("," & Chr(13) & Chr(10), ", " & Chr(13) & Chr(10))
                    EmailLog.WriteEntry("Email Log", "Email Processed: " & Subject, EventLogEntryType.Information)
                    CreateFile(msgType, Body)
                    Message.Unread = False
                    Message.Update()
                    Message.MoveTo(oldFolderEntryID)
                End If


                Body = String.Empty

            Catch ex As Exception
                EmailLog.WriteEntry("Email Log", "There was an error retrieving an email: " & Subject, EventLogEntryType.Warning)
                EmailLog.WriteEntry("Email Log", "Error: " & ex.ToString, EventLogEntryType.Error)
                EmailLog.WriteEntry("Email Log", "StackTrace: " & ex.StackTrace, EventLogEntryType.Error)

            End Try

           

        Next

        cdoSession.Logoff()



        cdoSession = Nothing
        cdoFolder = Nothing
        cdoField = Nothing

    End Sub
    Public Sub Delete(ByVal fileName As String)
        EmailLog.Source = "Email Log"
        Try
            System.IO.File.Delete(fileName)
        Catch ex As Exception
            EmailLog.WriteEntry("Email Log", "There was an error deleting a file", EventLogEntryType.Warning)
            EmailLog.WriteEntry("Email Log", "Error: " & ex.ToString, EventLogEntryType.Error)
            EmailLog.WriteEntry("Email Log", "StackTrace: " & ex.StackTrace, EventLogEntryType.Error)
        End Try
    End Sub
    Public Sub CreateFile(ByVal msgType As String, ByVal Body As String)
        EmailLog.Source = "Email Log"
        Dim FileName As String
        Select Case msgType
            Case "ForecastsIn"
                FileName = Me.GetConfigSetting("ForecastInQueue")
            Case "ForecastsOut"

                FileName = Me.GetConfigSetting("ForecastOutQueue")
        End Select

        FileName = FileName & Guid.NewGuid().ToString() & Date.Now.Millisecond & ".txt"
        EmailLog.WriteEntry("Email Log", "Filename: " & FileName, EventLogEntryType.Information)
        If Me.DoesExist(FileName) Then
            Me.Delete(FileName)
        End If


        Try
            Dim objFileStream As System.IO.FileStream
            objFileStream = System.IO.File.Create(FileName)
            objFileStream.Close()
            Dim objFileWrite As System.IO.StreamWriter = System.IO.File.AppendText(FileName)

            objFileWrite.Write(Body)

            objFileWrite.Close()
        Catch ex As Exception
            EmailLog.WriteEntry("Email Log", "There was an error writing a file: " & FileName, EventLogEntryType.Warning)
            EmailLog.WriteEntry("Email Log", "Error: " & ex.ToString, EventLogEntryType.Error)
            EmailLog.WriteEntry("Email Log", "StackTrace: " & ex.StackTrace, EventLogEntryType.Error)
        End Try

    End Sub
    Public Shared Function DoesExist(ByVal fileName As String) As Boolean

        Dim bReturnedValue As Boolean = False

        If System.IO.File.Exists(fileName) Then
            bReturnedValue = True
        Else
            bReturnedValue = False
        End If

        Return bReturnedValue

    End Function

    Private Function GetConfigSetting(ByVal key As String) As String
        Dim doc As New Xml.XmlDocument
        Dim strValue As String = String.Empty

        Try
            doc.Load("C:\Projects\EmailService\EmailRetrieve\Config.xml")
            strValue = doc.DocumentElement.SelectSingleNode(key).InnerText

        Catch ex As Exception
            strValue = String.Empty
            EmailLog.WriteEntry("Email Log.GetConfigurationSettings", "There was an error wgetting the congif settings " & ex.Message, EventLogEntryType.Warning)
        End Try

        Return strValue

    End Function



End Class
0
 

Author Comment

by:ecomaster
ID: 16251697
Thanks for the code, but for the moment I can't rely on CDO, since it's not installed by default during MS Office installation. So at the moment I'm looking for alternatives.
0
 
LVL 2

Expert Comment

by:Hamlet10
ID: 16255134
Here is some webdav code for access an exchange server. It is in C sharp.

Hope this is helpful


  try

                        {

                              ADODB.Connection oCn = new ADODB.Connection();

                              ADODB.Recordset oRs = new ADODB.Recordset();


                              ADODB.Fields oFields;
                              ADODB.Field oField;

                              // TODO:

                              string sFdUrl = "http://exh1/Exchange/cistest/Inbox";

 

                              oCn.Provider = "MSDAIPP.DSO";

                              oCn.Open(sFdUrl, "USERNAME", "PASSWORD", -1);

                               if(oCn.State == 1)
                              {
                                    Console.WriteLine("Good Connection");
                              }

                              else

                              {

                                    log.Error("Failed to connect to mail server : " + sFdUrl) ;

                              }



                              string strSql;

                              strSql = "";

                              strSql = "select ";

                              strSql = strSql + " \"urn:schemas:mailheader:content-class\"";

                              strSql = strSql + ", \"DAV:href\" ";

                              strSql = strSql + ", \"urn:schemas:mailheader:content-class\" ";

                              strSql = strSql + ", \"DAV:displayname\" ";

                              strSql = strSql + ", \"urn:schemas:mailheader:subject\" ";

                              strSql = strSql + ", \"DAV:subject\" ";

                              strSql = strSql + ", \"urn:schemas:mailheader:date\" ";

                              strSql = strSql + ", \"DAV:date\"";

                              strSql = strSql + " from scope ('shallow traversal of " + "\"";

                              strSql = strSql + sFdUrl + "\"') ";

                              strSql = strSql + " WHERE \"DAV:ishidden\" = false";

                              strSql = strSql + " AND \"DAV:isfolder\" = false";

 

 

                              oRs.Open(strSql, oCn,

                                    ADODB.CursorTypeEnum.adOpenUnspecified,

                                    ADODB.LockTypeEnum.adLockOptimistic, 1);

                       

 

                              oRs.MoveFirst();

                              while(!oRs.EOF )

                              {

                                    IFormatProvider culture = new CultureInfo("en-IE", true);

                                    string localDate = oRs.Fields["urn:schemas:mailheader:date"].Value.ToString() ;

 

                                    DateTime mailDate = DateTime.Parse(localDate,

                                          culture,

                                          DateTimeStyles.NoCurrentDateDefault);

                                    if(this.testStarted.CompareTo(mailDate) == -1)

                                    {

                                          log.Error("The error " + oRs.Fields["DAV:displayname"].Value.ToString() + " occoured please see " + oRs.Fields["DAV:href"].Value.ToString()) ;

 
                                          Trace.Write("Showing Mail For : " + mailDate.ToShortDateString() + " " +  mailDate.ToShortTimeString());

                                    }
                                    else
                                    {
                                        Trace.Write("Not showing : " + mailDate.ToShortDateString() + " " +  mailDate.ToShortTimeString()) ;
                                    }
                                    oRs.MoveNext() ;

                              }
                        }

                        catch(Exception ex)
                        {
                              Assert.Fail("Mail Retrival Failed. " + ex.Message + " " + ex.StackTrace) ;
                        }

}
0
 
LVL 2

Expert Comment

by:AJesani
ID: 16258496
Use of CDO Objects require Outlook to be installed on your machine and will use outlook configurations.
WebDav is kind of complicated to use. IMAP will be the best solution to retrieve emails
and Exchange SMTP to send emails - you can use System.Web.Mail in ASP.NET and specify smtp server as exchange to send emails.
For IMAP, if you want I can send you a simple Project, which has been written to retrieve emails thru IMAP.

Thanks,
Amit
0
 

Author Comment

by:ecomaster
ID: 16308803
I found just what I was looking for on this site: www.evocorp.com/Delphi/ADDExtendedMapi.htm. Thanks for the tips and pointing me in the right direction.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
Make the most of your online learning experience.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Six Sigma Control Plans

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question