From c39d0ea794d3ade09f4e7de7672ae2cd4771aadc Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Thu, 10 Feb 2022 16:56:12 +0100 Subject: [PATCH] Windows: Add filedrop class --- Windows/FileDrop.vb | 313 +++++++++++++++++++++++++++++++++++++++++ Windows/Windows.vbproj | 39 +++++ 2 files changed, 352 insertions(+) create mode 100644 Windows/FileDrop.vb diff --git a/Windows/FileDrop.vb b/Windows/FileDrop.vb new file mode 100644 index 00000000..bb97b8b2 --- /dev/null +++ b/Windows/FileDrop.vb @@ -0,0 +1,313 @@ +Imports System.Text +Imports DigitalData.Modules.Base +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.Language.Utils +Imports Microsoft.Office.Interop +Imports System.Windows + +Public Class FileDrop + Inherits BaseClass + + Public Enum FileFormat + OutlookAttachment + OutlookMail + ThunderbirdAttachment + ThunderbirdMail + MailWithoutAttachments + LocalFile + Unknown + End Enum + + Public Enum FileSource + DragDrop + FolderWatch + Attachment + End Enum + + Public Class DroppedFile + Public ReadOnly Property FilePath As String + Public Property FileFormat As FileFormat + Public Property FileSource As FileSource = FileSource.DragDrop + + Public Sub New(pFilePath As String) + FilePath = pFilePath + End Sub + + Public Sub New(pFilePath As String, pDropType As String) + MyClass.New(pFilePath) + + Select Case pDropType + Case "LOCAL_FILE" ' "|DROPFROMFSYSTEM|" + FileFormat = FileFormat.LocalFile + + Case "OUTLOOK_ATTACHMENT" ' "|OUTLOOK_ATTACHMENT|" + FileFormat = FileFormat.OutlookAttachment + + Case "OUTLOOK_MAIL" ' "|OUTLOOK_MESSAGE|" + FileFormat = FileFormat.OutlookMail + + Case "|MSGONLY|" + FileFormat = FileFormat.MailWithoutAttachments + + Case "|FW_OUTLOOK_MESSAGE|" + FileFormat = FileFormat.OutlookMail + FileSource = FileSource.FolderWatch + + Case "|FW_SIMPLEINDEXER|" + FileFormat = FileFormat.LocalFile + FileSource = FileSource.FolderWatch + + Case "|ATTMNTEXTRACTED|" + FileFormat = FileFormat.LocalFile + FileSource = FileSource.Attachment + + End Select + End Sub + End Class + + Public Sub New(pLogConfig As LogConfig) + MyBase.New(pLogConfig) + End Sub + + Public Function GetFileFormat(pEvent As DragEventArgs) As FileFormat + If IsThunderbird(pEvent) Then + If IsThunderbirdAttachment(pEvent) Then + Return FileFormat.ThunderbirdAttachment + + ElseIf IsThunderbirdMail(pEvent) Then + Return FileFormat.ThunderbirdMail + + Else + Return FileFormat.Unknown + End If + End If + + If IsOutlook(pEvent) Then + If IsOutlookAttachment(pEvent) Then + Return FileFormat.OutlookAttachment + + ElseIf IsOutlookMail(pEvent) Then + Return FileFormat.OutlookMail + + Else + Return FileFormat.Unknown + End If + End If + + If IsNormalFile(pEvent) Then + Return FileFormat.LocalFile + + Else + Return FileFormat.Unknown + End If + End Function + + Public Function GetFilePaths(pEvent As DragEventArgs) As List(Of DroppedFile) + Try + Dim oFormat = GetFileFormat(pEvent) + Dim oFiles As New List(Of DroppedFile) + + Select Case oFormat + Case FileFormat.OutlookAttachment, FileFormat.OutlookMail + Dim oFilePaths = GetOutlookFilePath(pEvent) + + For Each oPath In oFilePaths + oFiles.Add(New DroppedFile(oPath) With { + .FileFormat = oFormat + }) + Next + + Case Else + Dim oDroppedFiles As String() = GetFormat(pEvent, "FileDrop") + + If oDroppedFiles IsNot Nothing Then + For Each oPath In oDroppedFiles + oFiles.Add(New DroppedFile(oPath) With { + .FileFormat = oFormat + }) + Next + End If + + End Select + + Return oFiles + + Catch ex As Exception + Logger.Error(ex) + Return Nothing + + End Try + End Function + + Private Function GetOutlookFilePath(pEvent As DragEventArgs) As List(Of String) + Dim oTempPath As String = IO.Path.GetTempPath() + Dim oFileName As String = GetOutlookFileName(pEvent) + Dim oFilePath As String = IO.Path.Combine(oTempPath, oFileName) + Dim oContentsList As List(Of Byte()) = GetOutlookFileContents_FromInterop(pEvent) + + If oContentsList Is Nothing Then + Return Nothing + End If + + Dim oPathList As New List(Of String) + + For Each oContents In oContentsList + Using oFileStream As IO.FileStream = New IO.FileStream(oFilePath, IO.FileMode.Create) + oFileStream.Write(oContents, 0, oContents.Length) + oFileStream.Close() + End Using + + oPathList.Add(oFilePath) + Next + + Return oPathList + + End Function + + Private Function GetOutlookFileName(pEvent As DragEventArgs) As String + Dim oFileDescriptorSize = 512 + Dim oIndex As Integer = 76 + Dim oBuilder As New StringBuilder() + + Using oStream As IO.MemoryStream = GetFormat(pEvent, "FileGroupDescriptor") + Dim oFileGroupDescriptor As Byte() = New Byte(oFileDescriptorSize) {} + oStream.Read(oFileGroupDescriptor, 0, oFileDescriptorSize) + + While oFileGroupDescriptor(oIndex) <> 0 + Dim oChar = Convert.ToChar(oFileGroupDescriptor(oIndex)) + oBuilder.Append(oChar) + oIndex += 1 + End While + End Using + + Return oBuilder.ToString + End Function + + Private Function GetOutlookFileContents_FromDragEvent(pEvent As DragEventArgs) As List(Of Byte()) + Using oStream As IO.MemoryStream = pEvent.Data.GetData("FileContents", True) + If oStream Is Nothing Then + Return Nothing + End If + + Dim oContentLength = Convert.ToInt32(oStream.Length) + Dim oContents As Byte() = New Byte(oContentLength) {} + + oStream.Position = 0 + oStream.Read(oContents, 0, Convert.ToInt32(oContentLength)) + + Return New List(Of Byte()) From {oContents} + End Using + End Function + + Private Function GetOutlookFileContents_FromInterop(pEvent As DragEventArgs) As List(Of Byte()) + Dim oApp As Outlook.Application + Try + oApp = New Outlook.Application() + Catch ex As Exception + Logger.Error(ex) + Return Nothing + End Try + + Dim oResults As New List(Of Byte()) + Dim oMailItem As Outlook.MailItem + For oIndex As Integer = 1 To oApp.ActiveExplorer.Selection.Count + Try + oMailItem = oApp.ActiveExplorer.Selection.Item(oIndex) + + Dim oSubject As String = ConvertTextToSlug(oMailItem.Subject) + If oSubject = "" Then + oSubject = "NO_SUBJECT" + End If + Logger.Info("Subject Slug: [{0}]", oSubject) + + Dim oFileName As String = $"{oSubject}.msg" + Dim oTempPath As String = IO.Path.GetTempPath() + Dim oFilePath As String = IO.Path.Combine(oTempPath, oFileName) + + oMailItem.SaveAs(oFilePath) + + Using oFileStream As New IO.FileStream(oFilePath, IO.FileMode.Open) + + Dim oContents As Byte() = New Byte(oFileStream.Length) {} + oFileStream.Read(oContents, 0, oFileStream.Length) + + oResults.Add(oContents) + End Using + + Try + IO.File.Delete(oFilePath) + Catch ex As Exception + Logger.Warn("Temp file [{0}] could not be deleted!", oFilePath) + Logger.Error(ex) + End Try + + Return oResults + Catch ex As Exception + Logger.Error(ex) + End Try + Next + End Function + + Public Function GetFormat(pEvent As DragEventArgs, pFormat As String, pAutoConvert As Boolean) As Object + If CheckFor(pEvent, pFormat) Then + Dim oValue = pEvent.Data.GetData(pFormat, pAutoConvert) + Return oValue + Else + Return Nothing + End If + End Function + + Public Function GetFormat(pEvent As DragEventArgs, pFormat As String) As Object + Return GetFormat(pEvent, pFormat, False) + End Function + + Public Function CheckFor(pEvent As DragEventArgs, pFormat As String, pAutoConvert As Boolean) As Boolean + Dim oFormatExists = pEvent.Data.GetDataPresent(pFormat) + Logger.Debug("Format exists: [{0}]/[{1}]", pFormat, oFormatExists) + Return oFormatExists + End Function + + Public Function CheckFor(pEvent As DragEventArgs, pFormat As String) As Boolean + Return CheckFor(pEvent, pFormat, False) + End Function + + Public Function IsNormalFile(e As DragEventArgs) As Boolean + Return CheckFor(e, DataFormats.FileDrop, False) + End Function + + Public Function IsOutlook(e As DragEventArgs) As Boolean + Return CheckFor(e, "FileGroupDescriptor") AndAlso CheckFor(e, "FileDrop") + End Function + Public Function IsThunderbird(e As DragEventArgs) As Boolean + Return CheckFor(e, "text/x-moz-url") AndAlso CheckFor(e, "FileDrop") + End Function + + +#Region "Thunderbird" + Private Function IsOutlookMail(e As DragEventArgs) As Boolean + Return Not IsOutlookAttachment(e) AndAlso CheckFor(e, "RenPrivateSourceFolder") + End Function + + Private Function IsOutlookAttachment(e As DragEventArgs) As Boolean + Return IsOutlook(e) AndAlso + CheckFor(e, "RenPrivateItem") AndAlso + CheckFor(e, "ZoneIdentifier") + End Function +#End Region + +#Region "Outlook" + Private Function IsThunderbirdMail(e As DragEventArgs) As Boolean + Return Not IsThunderbirdAttachment(e) + End Function + + Private Function IsThunderbirdAttachment(e As DragEventArgs) As Boolean + Return IsThunderbird(e) AndAlso + CheckFor(e, "text/x-moz-url-data") AndAlso + CheckFor(e, "text/x-moz-url-desc") + End Function +#End Region + + + + +End Class diff --git a/Windows/Windows.vbproj b/Windows/Windows.vbproj index 92b0b6dd..c5eacc15 100644 --- a/Windows/Windows.vbproj +++ b/Windows/Windows.vbproj @@ -83,8 +83,10 @@ Form + + @@ -129,10 +131,47 @@ + + {6ea0c51f-c2b1-4462-8198-3de0b32b74f8} + Base + + + {d3c8cfed-d6f6-43a8-9bdf-454145d0352f} + Language + {903B2D7D-3B80-4BE9-8713-7447B704E1B0} Logging + + + {2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} + 2 + 8 + 0 + primary + False + True + + + {00062FFF-0000-0000-C000-000000000046} + 9 + 6 + 0 + primary + False + True + + + {00020430-0000-0000-C000-000000000046} + 2 + 0 + 0 + primary + False + True + + \ No newline at end of file