Imports System.IO Imports System.Guid Imports System.Text.RegularExpressions Imports Limilabs.Mail Imports DigitalData.Modules.Base Imports DigitalData.Modules.Logging Public Class ClassFileHandler Inherits BaseClass Public Sub New(pLogConfig As LogConfig) MyBase.New(pLogConfig) End Sub Public Property TempFiles As New List(Of String) Private Function GetTempPath(pSourceFilePath As String, pNewFileName As String, pSubfolder As String) As String Try Dim oTempDirectory = Path.GetTempPath() Dim oTempSubDirectory As String = Path.Combine(oTempDirectory, pSubfolder) ' Try to create a subdirectory for all temp files so it will be easier to clean up ' these files by just deleting the whole fucking folder. 🤬 If Not Directory.Exists(oTempSubDirectory) Then Try Directory.CreateDirectory(oTempSubDirectory) Catch ex As Exception Logger.Error(ex) ' We could not create a subfolder ' Set the final directory to the default temp oTempSubDirectory = oTempDirectory End Try End If ' Copy the file to the new location Dim oNewPath = Path.Combine(oTempSubDirectory, pNewFileName) File.Copy(pSourceFilePath, oNewPath) Return oNewPath Catch ex As Exception Return Nothing End Try End Function Public Sub Clear_Tempfiles() For Each oFile In TempFiles Try System.IO.File.Delete(oFile) Catch ex As Exception Logger.Error(ex) End Try Next TempFiles.Clear() End Sub Public Function Decide_FileHandle(pFilepath As String, pHandletype As String) As Boolean Try ''TODO: Before doing anything, clean the filename 'Dim oFilename = IO.Path.GetFileName(pFilepath) 'Dim oCleanFileName = Utils.RemoveInvalidCharacters(oFilename) 'Dim oTempDirectory = IO.Path.GetTempPath() 'Dim oTempFilePath = IO.Path.Combine(oTempDirectory, oCleanFileName) 'Try ' TEMP_FILES.Add(oTempFilePath) ' LOGGER.Debug("Copying file") ' LOGGER.Debug(pFilepath) ' LOGGER.Debug(oTempFilePath) ' IO.File.Copy(pFilepath, oTempFilePath, True) 'Catch ex As Exception ' LOGGER.Error(ex) ' Throw ex 'End Try Dim oTempFilePath = pFilepath Dim oInboxRegex As New Regex("\.INBOX\d+$") If oInboxRegex.IsMatch(oTempFilePath) Then Logger.Info("Renaming INBOX file to EML") Try Dim oInfo As New FileInfo(oTempFilePath) Logger.Info("Old Name: {0}", oInfo.Name) Dim oNewName = $"{oInfo.Name}.eml" Logger.Info("New Name: {0}", oNewName) Dim oTempDirectory = IO.Path.GetTempPath() Dim oNewPath = IO.Path.Combine(oTempDirectory, oNewName) IO.File.Copy(oInfo.FullName, oNewPath) 'TEMP_FILES.Add(oNewPath) TempFiles.Add(oNewPath) oTempFilePath = oNewPath Catch ex As Exception Logger.Error(ex) End Try End If If oTempFilePath.ToUpper.EndsWith(".MSG") Or oTempFilePath.ToUpper.EndsWith(".EML") Then CURRENT_MESSAGEID = "" Dim oMail As IMail = EMAIL.Load_Email(oTempFilePath) If oMail.Attachments.Count > 0 Then Dim oTitle As String Dim oMessage As String If USER_LANGUAGE = "de-DE" Then oTitle = "Nachfrage zur Indexierung:" oMessage = "Achtung: Die Email enthält Anhänge!" & vbNewLine & "Wollen Sie die Anhänge separat indexieren und herauslösen?" Else oTitle = "Question about Indexing:" oMessage = "Attention: This Email contains Attachments!" & vbNewLine & "Do you want to extract the attachments and index them seperately?" End If Dim oResult As DialogResult ' Weird hack to force messagebox to be topmost ' https://stackoverflow.com/questions/1220882/keep-messagebox-show-on-top-of-other-application-using-c-sharp oResult = MessageBox.Show(oMessage, oTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) If oResult = MsgBoxResult.Yes Then Dim oIsFolderWatch = pHandletype.StartsWith("|FW") Return Save_EmailAndAttachmentsToDisk(oTempFilePath, oIsFolderWatch) End If End If End If If oTempFilePath.ToUpper.EndsWith(".LNK") Then If USER_LANGUAGE = "de-DE" Then MsgBox("Verknüpfungen können nicht abgelegt werden!", MsgBoxStyle.Critical, "File Flow") Else MsgBox("Shortcuts cannot be droppped!", MsgBoxStyle.Critical, "File Flow") End If Return False End If Return Insert_GI_File(oTempFilePath, pHandletype) Catch ex As Exception MsgBox("Unexpected Error in Decide_FileHandle: " & ex.Message, MsgBoxStyle.Critical) Return False End Try End Function Private Function Save_EmailAndAttachmentsToDisk(pEmailFilePath As String, Optional pFolderWatch As Boolean = False) As Boolean Try Dim oMessageOnlyMarker As String = "|MSGONLY|" Dim oExtractedAttachmentMarker As String = "|ATTMNTEXTRACTED|" If pFolderWatch = True Then oMessageOnlyMarker = "|FW_MSGONLY|" oExtractedAttachmentMarker = "|FW_ATTMNTEXTRACTED|" End If Dim oSuccess As Boolean = False Logger.Info("Converting file to Eml if needed: [{0}]", pEmailFilePath) Dim oEmail As IMail = EMAIL.Load_Email(pEmailFilePath) If oEmail.MessageID IsNot Nothing Then CURRENT_MESSAGEID = oEmail.MessageID Else Logger.Info("Es konnte keine Message-ID gelesen werden. Eine GUID wird erzeugt!") CURRENT_MESSAGEID = NewGuid.ToString() End If Dim oEmailFilePathWithoutAttachments = EMAIL.Remove_AttachmentsFromEmail(pEmailFilePath, "_excl_attachments") TempFiles.Add(oEmailFilePathWithoutAttachments) 'TEMP_FILES.Add(oEmailFilePathWithoutAttachments) If Insert_GI_File(oEmailFilePathWithoutAttachments, oMessageOnlyMarker) = True Then oSuccess = True Dim oAttachments As List(Of String) = EMAIL.Save_AttachmentsToDisk(pEmailFilePath) Logger.Debug("Saved [{0}] attachments to disk.", oAttachments.Count) For Each oAttachment In oAttachments 'TEMP_FILES.Add(oAttachment) TempFiles.Add(oAttachment) Logger.Debug("Saved attachment [{0}].", oAttachment) oSuccess = Insert_GI_File(oAttachment, oExtractedAttachmentMarker) If oSuccess = False Then Logger.Warn("Saving attachment to disk failed: [{0}]", oAttachment) Exit For End If Next End If Return oSuccess Catch ex As Exception Logger.Warn("Saving email to disk failed (Email_Decay)") Logger.Error(ex) Return False End Try End Function 'Private Shared Function Email_Decay(msgname As String, Optional FW As Boolean = False) ' Try ' Dim msgonly As String = "|MSGONLY|" ' Dim ATT_EXTR As String = "|ATTMNTEXTRACTED|" ' If FW = True Then ' msgonly = "|FW_MSGONLY|" ' ATT_EXTR = "|FW_ATTMNTEXTRACTED|" ' End If ' Dim erfolgreich As Boolean = False ' Dim msg As New MSG.Message(msgname) ' If msg.InternetMessageId IsNot Nothing Then ' CURRENT_MESSAGEID = msg.InternetMessageId ' Else ' LOGGER.Info("Es konnte keine Message-ID gelesen werden. Eine GUID wird erzeugt!") ' Dim sGUID As String ' sGUID = System.Guid.NewGuid.ToString() ' CURRENT_MESSAGEID = sGUID ' End If ' 'Nur die MSGDatei ablegen ' Dim tempfile As String = Path.Combine(Path.GetTempPath, Path.GetFileNameWithoutExtension(msgname) & "_excl_att.msg") ' If File.Exists(tempfile) Then ' File.Delete(tempfile) ' End If ' Dim _msgEXAtt As New Msg.Message(msgname) ' _msgEXAtt.Attachments.Clear() ' _msgEXAtt.Save(tempfile) ' 'Datei in Array zum Templöschen speichern ' TEMP_FILES.Add(tempfile) ' If Insert_GI_File(tempfile, msgonly) = True Then ' erfolgreich = True ' 'Hier nun die Anhänge herauslösen ' Dim _msg As New Msg.Message(msgname) ' Dim i1 As Integer = 1 ' LOGGER.Info(">> Anzahl der Attachments: " & _msg.Attachments.Count) ' For Each attachment As Independentsoft.Msg.Attachment In _msg.Attachments ' If erfolgreich = False Then ' Exit For ' End If ' Dim attachment_name As String ' If attachment.LongFileName Is Nothing Then ' attachment_name = attachment.DisplayName ' Else ' attachment_name = attachment.LongFileName ' End If ' If attachment.EmbeddedMessage IsNot Nothing Then ' attachment_name = Utils.RemoveInvalidCharacters(attachment_name) ' tempfile = Path.Combine(Path.GetTempPath, attachment_name & ".msg") ' tempfile = ClassFilehandle.Versionierung_Datei(tempfile) ' If tempfile <> String.Empty Then ' Dim oMessage = attachment.EmbeddedMessage ' oMessage.IsEmbedded = False ' oMessage.Save(tempfile) ' TEMP_FILES.Add(tempfile) ' LOGGER.Info(">> Attachment (" & i1 & "):" & tempfile) ' erfolgreich = Insert_GI_File(tempfile, ATT_EXTR) ' i1 += 1 ' End If ' ElseIf Not attachment_name.Contains("inline") Then ' 'Sonderzeichen entfernen ' attachment_name = Utils.RemoveInvalidCharacters(attachment_name) ' tempfile = Path.Combine(Path.GetTempPath, attachment_name) ' tempfile = ClassFilehandle.Versionierung_Datei(tempfile) ' If tempfile <> "" Then ' attachment.Save(tempfile) ' 'Datei in Array zum Templöschen speichern ' TEMP_FILES.Add(tempfile) ' LOGGER.Info(">> Attachment (" & i1 & "):" & tempfile) ' 'nun der Insert des Anhanges ' erfolgreich = Insert_GI_File(tempfile, ATT_EXTR) ' i1 += 1 ' End If ' End If ' Next ' End If ' Return erfolgreich ' Catch ex As Exception ' MsgBox("Error in Email_Decay: " & ex.Message, MsgBoxStyle.Critical) ' End Try 'End Function Private Function Insert_GI_File(filename As String, handleType As String) Try filename = filename.Replace("'", "''") Dim oHash As String = String.Empty If File.Exists(filename) Then If (filename.ToUpper.EndsWith(".MSG") Or filename.ToUpper.EndsWith(".EML")) And (handleType = "|OUTLOOK_MESSAGE|" Or handleType = "|MSGONLY|") Then oHash = FILESYSTEM.GetChecksumFromString(filename) Else oHash = FILESYSTEM.GetChecksum(filename) End If End If Dim filename_only As String = Path.GetFileName(filename) Dim ins As String = $"INSERT INTO TBGI_FILES_USER (FILENAME2WORK, USER@WORK, HANDLE_TYPE, FILENAME_ONLY, FILE_HASH) VALUES ('{filename}','{Environment.UserName}','{handleType}','{filename_only}', '{oHash}')" Return DATABASE_ECM.ExecuteNonQuery(ins) Catch ex As Exception Return False End Try End Function Public Function IsFileInUse(ByVal fullFilePath As String) As Boolean ' Gibt zurück, ob die übergebene Datei momentan exklusiv zu haben ist. ' Prüft, ob die angegeben Datei aktuell durch eine ' andere Anwendung in Benutzung ist Dim ff As Integer = FreeFile() If File.Exists(fullFilePath) Then Try ' Versuchen, die Datei mit *exklusiven* Lese- und ' Schreibrechten zu öffnen FileOpen(ff, fullFilePath, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite) Catch ex As Exception ' Ist ein Fehler aufgetreten, so wird nach außen hin generell ' davon ausgegangen, dass die Datei in Benutzung ist (obwohl ' auch andere Ursachen, etwa Rechteprobleme, möglich sind). Logger.Info(">> FileInUse Message: " & ex.Message) IsFileInUse = True Finally ' Die eventuell geöffnete Datei schließen FileClose(ff) End Try Return False End If End Function Public Function Versionierung_Datei(Dateiname As String) Dim extension Dim _NewFileString Try Dim version As Integer = 1 Dim Stammname As String = Path.GetDirectoryName(Dateiname) & "\" & Path.GetFileNameWithoutExtension(Dateiname).Trim() extension = Path.GetExtension(Dateiname) Dim _neuername As String = Stammname 'Dim MoveFilename As String = DATEINAME.Replace(element.Value, "") 'Überprüfen ob File existiert If File.Exists(_neuername & extension) = False Then _NewFileString = _neuername Else Do While File.Exists(_neuername & extension) version += 1 _neuername = Stammname & "~" & version _NewFileString = _neuername Loop End If Return _NewFileString & extension Catch ex As Exception Logger.Info(" - Error in versioning file - error: " & vbNewLine & ex.Message) Logger.Error(ex) MsgBox(ex.Message, MsgBoxStyle.Critical, "Error in versioning file:") Return "" End Try End Function '' ''' Ersetzt alle nicht zulässigen Zeichen im angegebenen Dateinamen ''' ''' Dateiname ohne Pfadangabe ''' Ersatzzeichen für alle unzulässigen Zeichen ''' im Dateinamen Public Function CleanFilename(ByVal sFilename As String, Optional ByVal REPLACEChar As String = "") As String Logger.Info(" >> Filename before CleanFilename: '" & sFilename & "'") If sFilename.Contains(".\") Then sFilename = sFilename.Replace(".\", "\") End If 'If sFilename.Contains("'") Then ' sFilename = sFilename.Replace("'", "") 'End If 'If sFilename.Contains("..") Then ' sFilename = sFilename.Replace("..", ".") 'End If ' alle nicht zulässigen Zeichen ersetzen sFilename = System.Text.RegularExpressions.Regex.Replace(sFilename, REGEX_CLEAN_FILENAME, REPLACEChar) sFilename = System.Text.RegularExpressions.Regex.Replace(sFilename, "[\\/:*?""<>|\r\n]", "", System.Text.RegularExpressions.RegexOptions.Singleline) 'Dim oCleanFileName As String = String.Join(REPLACEChar, sFilename.Split(Path.GetInvalidFileNameChars())) Dim oCleanFileName As New System.IO.FileInfo(System.Text.RegularExpressions.Regex.Replace(sFilename, String.Format("[{0}]", String.Join(String.Empty, Path.GetInvalidFileNameChars)), REPLACEChar)) Logger.Info(" >> Filename after CleanFilename: '" & sFilename & "'") Return sFilename End Function End Class