From 1a0736187ecdc2365995cdde9dc2fa16e8d2a628 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Wed, 10 Apr 2019 16:13:51 +0200 Subject: [PATCH] use S22.Imap for fetching Messages --- App/CONFIG_APP/CONFIG_APP.vbproj | 13 +- App/CONFIG_APP/frmMain.vb | 8 +- .../DigitalData.EMLProfiler.vbproj | 3 + App/DigitalData.EMLProfiler/clsEmail.IMAP.vb | 237 +++++++++++++----- App/DigitalData.EMLProfiler/clsWorker.vb | 4 +- App/DigitalData.EMLProfiler/packages.config | 1 + 6 files changed, 193 insertions(+), 73 deletions(-) diff --git a/App/CONFIG_APP/CONFIG_APP.vbproj b/App/CONFIG_APP/CONFIG_APP.vbproj index 6a0d8f5..1dfe0e0 100644 --- a/App/CONFIG_APP/CONFIG_APP.vbproj +++ b/App/CONFIG_APP/CONFIG_APP.vbproj @@ -57,10 +57,6 @@ - - False - ..\DigitalData.EMLProfiler\bin\Debug\DigitalData.EMLProfiler.dll - ..\..\..\DDMonorepo\Modules.Logging\bin\Debug\DigitalData.Modules.Logging.dll @@ -72,6 +68,9 @@ ..\packages\NLog.4.5.9\lib\net45\NLog.dll + + ..\packages\S22.Imap.3.6.0.0\lib\net40\S22.Imap.dll + @@ -191,5 +190,11 @@ + + + {9f748dcd-952e-40a0-9dad-65bf8a39b231} + DigitalData.EMLProfiler + + \ No newline at end of file diff --git a/App/CONFIG_APP/frmMain.vb b/App/CONFIG_APP/frmMain.vb index 676044b..ff72104 100644 --- a/App/CONFIG_APP/frmMain.vb +++ b/App/CONFIG_APP/frmMain.vb @@ -664,9 +664,13 @@ Public Class frmMain Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click My.Settings.Save() Dim PWPlain = _Encryption.DecryptData(EMAIL_PWTextBox.Text) - If _emailIMAP.TEST_IMAP_COLLECT(txtInboxname.Text, EMAIL_SMTPTextBox.Text, PORT_INTextBox.Text, EMAIL_USERTextBox.Text, PWPlain) = False Then - MsgBox("Access Imap NOT successfull", MsgBoxStyle.Critical) + Dim oResult = _emailIMAP.TestIMAPLogin(EMAIL_SMTPTextBox.Text, PORT_INTextBox.Text, EMAIL_USERTextBox.Text, PWPlain, txtInboxname.Text) + + If oResult = False Then + MsgBox("Access Imap NOT successfull", MsgBoxStyle.Critical) + Else + MsgBox("Test Successful!", MsgBoxStyle.Information) End If End Sub diff --git a/App/DigitalData.EMLProfiler/DigitalData.EMLProfiler.vbproj b/App/DigitalData.EMLProfiler/DigitalData.EMLProfiler.vbproj index a621699..7f5a646 100644 --- a/App/DigitalData.EMLProfiler/DigitalData.EMLProfiler.vbproj +++ b/App/DigitalData.EMLProfiler/DigitalData.EMLProfiler.vbproj @@ -72,6 +72,9 @@ ..\packages\NLog.4.5.8\lib\net45\NLog.dll + + ..\packages\S22.Imap.3.6.0.0\lib\net40\S22.Imap.dll + diff --git a/App/DigitalData.EMLProfiler/clsEmail.IMAP.vb b/App/DigitalData.EMLProfiler/clsEmail.IMAP.vb index 2cc7748..7966f0d 100644 --- a/App/DigitalData.EMLProfiler/clsEmail.IMAP.vb +++ b/App/DigitalData.EMLProfiler/clsEmail.IMAP.vb @@ -4,6 +4,10 @@ Imports Independentsoft.Email.Mime Imports DigitalData.EMLProfiler.ClassCurrent Imports DigitalData.Modules.Logging Imports AE +Imports System.Net +Imports System.Reflection +Imports System.IO + Public Class clsEmailIMAP Private Shared Logger As DigitalData.Modules.Logging.Logger @@ -13,87 +17,188 @@ Public Class clsEmailIMAP 'Private Shared Sub OnWriteLog(ByVal sender As Object, ByVal e As WriteLogEventArgs) ' Logger.Info(e.Log) 'End Sub - Public Function IMAP_COLLECT() + + Public Function TestIMAPLogin(Server As String, Port As Integer, Username As String, Password As String, Inbox As String) As Boolean + Logger.Debug("Testing Login to Server {0}:{1} with user {2}", Server, Port, Username) + Try - Logger.Info(String.Format("Working on IMAP_COLLECT.....")) - Logger.Debug(String.Format("Working on IMAP_COLLECT.....")) - Dim oClient As New Independentsoft.Email.Imap.ImapClient(MAIL_SERVER, MAIL_PORT) - - oClient.ValidateRemoteCertificate = False - oClient.Connect() - oClient.Login(MAIL_USER, MAIL_USER_PW) - oClient.SelectFolder("Inbox") - Dim oEnvelopes As Independentsoft.Email.Imap.Envelope() = oClient.ListMessages() - Dim oCount As Integer = 0 - For i As Integer = 0 To oEnvelopes.Length - 1 - If Not IsNothing(oEnvelopes(i).Subject) Then - 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then - Logger.Info($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") - Dim oMessage As Mime.Message = oClient.GetMessage(oEnvelopes(i).UniqueID) - If Not IsNothing(oMessage) Then - oCount += 1 - MAIL_LIST.Add(oMessage) - End If - 'End If + Logger.Debug("Connecting...") + Using oClient As New S22.Imap.ImapClient(Server, Port, Username, Password, S22.Imap.AuthMethod.Login, True) + If Not oClient.Authed Then + Logger.Warn("Connected to server but authentication failed.") + Return False End If - Next - oClient.Disconnect() - Logger.Debug($"{oCount.ToString} messages will be worked..") - Logger.Debug("IMAP_COLLECT finished!") - Return True + Logger.Debug("Connection successful") + + Logger.Debug("Fetching MessageIds..") + Dim oMessageIds As IEnumerable(Of UInteger) = oClient.Search(S22.Imap.SearchCondition.Unseen, Inbox) + + Logger.Debug("Found {0} messages", oMessageIds.Count) + Logger.Debug("Fetching messages...") + + Dim oMessages As IEnumerable(Of Mail.MailMessage) = oClient.GetMessages(oMessageIds, False, Inbox) + Logger.Debug("Messages fetched") + + oClient.Dispose() + + Return True + End Using Catch ex As Exception - Logger.Error(ex, "Unexpected Error in IMAP COLLECT:") + Logger.Error(ex) Return False End Try End Function - Public Function TEST_IMAP_COLLECT(INBOXNAME As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) - Try - Logger.Info(String.Format("Working on TEST_IMAP_COLLECT.....")) - Dim oLogPath = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "Log\logindependentSoft.txt") - Logger.Debug($"IsoftLog: {oLogPath}...") - Dim oindependentLogger As New Independentsoft.Email.Logger(oLogPath) - - Dim oImapClient As New Independentsoft.Email.Imap.ImapClient(MYMAIL_SERVER, MYMAIL_PORT) - oImapClient.Logger = oindependentLogger - oImapClient.ValidateRemoteCertificate = False - oImapClient.Connect() - Logger.Debug($"oImapClient connected...") - Try - oImapClient.Login(MAIL_USER, MAIL_USER_PW, AuthenticationType.Login) - Catch ex As Exception - MsgBox($"Unexpected error in (oImapClient.Login): {ex.Message}") - Logger.Info($"Unexpected error in oImapClient.Login - User: [{MYMAIL_USER}] PW: [{MYMAIL_USER_PW}]") - Logger.Warn(ex.StackTrace.ToString) - Logger.Warn(ex.Message) - oImapClient.Logger.Close() - Logger.Error(ex) - Return False - End Try - oImapClient.SelectFolder(INBOXNAME) - Dim oEnvelopes As Independentsoft.Email.Imap.Envelope() = oImapClient.ListMessages() + Public Function FetchIMAPMessages(Server As String, Port As Integer, Username As String, Password As String, Inbox As String) As Boolean + Logger.Debug("Connecting to Server {0}:{1} with user {2}", Server, Port, Username) - For i As Integer = 0 To oEnvelopes.Length - 1 - If Not IsNothing(oEnvelopes(i).Subject) Then - 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then - MsgBox($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") - Dim message As Mime.Message = oImapClient.GetMessage(oEnvelopes(i).UniqueID) + Try + Logger.Debug("Connecting...") + Using oClient As New S22.Imap.ImapClient(Server, Port, Username, Password, S22.Imap.AuthMethod.Login, True) + If Not oClient.Authed Then + Logger.Warn("Connected to server but authentication failed.") + Return False End If - Next + Logger.Debug("Connection successful") - oImapClient.Disconnect() - oImapClient.Logger.Close() - Logger.Info("TEST_IMAP_COLLECT finished!") - Return True + Logger.Debug("Fetching MessageIds..") + Dim oMessageIds As IEnumerable(Of UInteger) = oClient.Search(S22.Imap.SearchCondition.Unseen, Inbox) - Catch ex As Exception - Logger.Info($"Unexpected error in TEST_IMAP_COLLECT - User: [{MYMAIL_USER}] PW: [{MYMAIL_USER_PW}]") - MsgBox($"Unexpected error in TEST_IMAP_COLLECT: {ex.Message}") - Logger.Error(ex, "Unexpected Error in TEST_IMAP_COLLECT:") + Logger.Debug("Found {0} messages", oMessageIds.Count) + Logger.Debug("Fetching messages...") + + For Each oMessageId As UInteger In oMessageIds + Dim oMessage = oClient.GetMessage(oMessageId, False, Inbox) + Dim oTempPath = Path.GetTempFileName() + Dim oResult = WriteMessageToFile(oMessage, oTempPath) + + Dim oMsg As New Message(oTempPath) + MAIL_LIST.Add(oMsg) + Try + File.Delete(oTempPath) + Catch ex As Exception + Logger.Error(ex) + Logger.Warn("Temp file could not be deleted") + End Try + Next + + Logger.Debug("Messages fetched") + End Using + Return True + Catch ex As Exception + Logger.Error(ex) Return False End Try End Function + + ''' + ''' Uses a private API from MailWriter to write a MailMessage to disk. + ''' May break in future versions of .NET + ''' + Public Function WriteMessageToFile(Message As Mail.MailMessage, Filename As String) As Boolean + Dim oAssembly As Assembly = GetType(Mail.SmtpClient).Assembly + Dim oMailWriterType As Type = oAssembly.[GetType]("System.Net.Mail.MailWriter") + + Try + Using oStream As New FileStream(Filename, FileMode.Create) + Dim oMailWriterConstructor As ConstructorInfo = oMailWriterType.GetConstructor( + BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Type() {GetType(Stream)}, Nothing + ) + Dim oMailWriter As Object = oMailWriterConstructor.Invoke(New Object() {oStream}) + Dim sendMethod As MethodInfo = GetType(Mail.MailMessage).GetMethod("Send", BindingFlags.Instance Or BindingFlags.NonPublic) + sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, {oMailWriter, True, True}, Nothing) + End Using + + Return True + Catch ex As Exception + Return Nothing + End Try + End Function + + + 'Public Function IMAP_COLLECT() + ' Try + ' Logger.Info(String.Format("Working on IMAP_COLLECT.....")) + ' Logger.Debug(String.Format("Working on IMAP_COLLECT.....")) + ' Dim oClient As New Independentsoft.Email.Imap.ImapClient(MAIL_SERVER, MAIL_PORT) + + ' oClient.ValidateRemoteCertificate = False + ' oClient.Connect() + ' oClient.Login(MAIL_USER, MAIL_USER_PW) + ' oClient.SelectFolder("Inbox") + ' Dim oEnvelopes As Independentsoft.Email.Imap.Envelope() = oClient.ListMessages() + ' Dim oCount As Integer = 0 + ' For i As Integer = 0 To oEnvelopes.Length - 1 + ' If Not IsNothing(oEnvelopes(i).Subject) Then + ' 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then + ' Logger.Info($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") + ' Dim oMessage As Mime.Message = oClient.GetMessage(oEnvelopes(i).UniqueID) + ' If Not IsNothing(oMessage) Then + ' oCount += 1 + ' MAIL_LIST.Add(oMessage) + ' End If + ' 'End If + ' End If + ' Next + ' oClient.Disconnect() + ' Logger.Debug($"{oCount.ToString} messages will be worked..") + ' Logger.Debug("IMAP_COLLECT finished!") + ' Return True + ' Catch ex As Exception + ' Logger.Error(ex, "Unexpected Error in IMAP COLLECT:") + ' Return False + ' End Try + 'End Function + 'Public Function TEST_IMAP_COLLECT(INBOXNAME As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) + ' Try + ' Logger.Info(String.Format("Working on TEST_IMAP_COLLECT.....")) + ' Dim oLogPath = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "Log\logindependentSoft.txt") + ' Logger.Debug($"IsoftLog: {oLogPath}...") + ' Dim oindependentLogger As New Independentsoft.Email.Logger(oLogPath) + + ' Dim oImapClient As New Independentsoft.Email.Imap.ImapClient(MYMAIL_SERVER, MYMAIL_PORT) + ' oImapClient.Logger = oindependentLogger + ' oImapClient.ValidateRemoteCertificate = False + ' oImapClient.Connect() + ' Logger.Debug($"oImapClient connected...") + ' Try + ' oImapClient.Login(MAIL_USER, MAIL_USER_PW, AuthenticationType.Login) + ' Catch ex As Exception + ' MsgBox($"Unexpected error in (oImapClient.Login): {ex.Message}") + ' Logger.Info($"Unexpected error in oImapClient.Login - User: [{MYMAIL_USER}] PW: [{MYMAIL_USER_PW}]") + ' Logger.Warn(ex.StackTrace.ToString) + ' Logger.Warn(ex.Message) + ' oImapClient.Logger.Close() + ' Logger.Error(ex) + ' Return False + ' End Try + + ' oImapClient.SelectFolder(INBOXNAME) + ' Dim oEnvelopes As Independentsoft.Email.Imap.Envelope() = oImapClient.ListMessages() + + ' For i As Integer = 0 To oEnvelopes.Length - 1 + ' If Not IsNothing(oEnvelopes(i).Subject) Then + ' 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then + ' MsgBox($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") + ' Dim message As Mime.Message = oImapClient.GetMessage(oEnvelopes(i).UniqueID) + ' End If + ' Next + + ' oImapClient.Disconnect() + ' oImapClient.Logger.Close() + ' Logger.Info("TEST_IMAP_COLLECT finished!") + ' Return True + + ' Catch ex As Exception + ' Logger.Info($"Unexpected error in TEST_IMAP_COLLECT - User: [{MYMAIL_USER}] PW: [{MYMAIL_USER_PW}]") + ' MsgBox($"Unexpected error in TEST_IMAP_COLLECT: {ex.Message}") + ' Logger.Error(ex, "Unexpected Error in TEST_IMAP_COLLECT:") + + ' Return False + ' End Try + 'End Function + Public Function TEST_AEIMAP_COLLECT(INBOXNAME As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) Try Logger.Info(String.Format("Working on TEST_AEIMAP_COLLECT.....")) diff --git a/App/DigitalData.EMLProfiler/clsWorker.vb b/App/DigitalData.EMLProfiler/clsWorker.vb index 73352de..a80d5f9 100644 --- a/App/DigitalData.EMLProfiler/clsWorker.vb +++ b/App/DigitalData.EMLProfiler/clsWorker.vb @@ -125,7 +125,9 @@ Public Class clsWorker Case "POP" pollresult = _email.POP3_COLLECT() Case "IMAP" - pollresult = _emailIMAP.IMAP_COLLECT() + 'pollresult = _emailIMAP.IMAP_COLLECT() + ' 09.04.19: Use S22.Imap instead of IndependentSoft ImapClient + pollresult = _emailIMAP.FetchIMAPMessages(MAIL_SERVER, MAIL_PORT, MAIL_USER, MAIL_USER_PW, "Inbox") End Select End If diff --git a/App/DigitalData.EMLProfiler/packages.config b/App/DigitalData.EMLProfiler/packages.config index 77ca987..7772d23 100644 --- a/App/DigitalData.EMLProfiler/packages.config +++ b/App/DigitalData.EMLProfiler/packages.config @@ -2,4 +2,5 @@ + \ No newline at end of file