Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Почтовая программа+Письмо в Inbox+DragDrop / 3 сообщений из 3, страница 1 из 1
28.06.2016, 15:14
    #39263914
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почтовая программа+Письмо в Inbox+DragDrop
В общем есть Почта Windows(бывший OE), в ней папка Inbox, в ней письма.
Опыт использования показывает, что если перетащить письмо из Inbox в папку проводника, то там создается .eml (перетаскиваемое письмо c именем = Тема Письма).
Все письма в оригинальной базе уже хранятся в .eml файлах типа
\Windows Mail\Local Folders\Inbox\729E5421-0000C80D.eml

Задача: через DragDrop получить ссылку на целиковый .eml файл соответствующий выбранному письму.
Грубо: перетащил письмо в контрол, далее работаю с этим .eml, например через CDO.Message

Кодируем текстбох (AllowDrop=true):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
 Private Sub TextBoxEmlPath_DragEnter(sender As Object, e As DragEventArgs) Handles TextBoxEmlPath.DragEnter
    For i As Integer = 0 To UBound(e.Data.GetFormats())
      Debug.Print(e.Data.GetFormats()(i))
    Next
    'If e.Data.GetDataPresent(DataFormats.FileDrop) Then
    '  e.Effect = DragDropEffects.Copy
    'End If
    e.Effect = DragDropEffects.Copy
  End Sub



Тащим в него письмо. Дебаг дает следующие форматы:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
Windows Mail Messages
FileGroupDescriptor
FileGroupDescriptorW
FileContents
Internet Message (rfc822/rfc1522)
HTML Format
System.String
UnicodeText
Text



Пытаемся извлечь информацию:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
  Private Sub TextBoxEmlPath_DragDrop(sender As Object, e As DragEventArgs) Handles TextBoxEmlPath.DragDrop
    'Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
    'For Each path In files
    '  TextBoxEmlPath.Text = path
    'Next
    TextBoxEmlPath.Text = e.Data.GetData(DataFormats.Html)
    'TextBoxEmlPath.Text = e.Data.GetData(DataFormats.Text)
  End Sub



e.Data.GetData(DataFormats.Html) -это HTML-код страницы письма (если оно HTML)
e.Data.GetData(DataFormats.Text)-это текст письма (если оно PlainText, либо преобразование HTML->TEXT) + заголовок From/To/Subject/Date: 24 июня 2016 г. 13:24 (фигово что дата на русском)

Уже неплохо. На этом интуиция моя закончилась.
Но мне б хотелось получить .eml целиком

Предполагаю что можно извлечь
1) путь к .eml в базе программы (не уверен, потому что в старом OE не было отдельных .eml в базе, а был здоровый файл базы, при этом .eml при перетаскивании в папку писался точно также)
2) тупо данные (набор байтов), из которых пишется полный .eml при перетаскивании

Есть идеи?
Подозреваю что надо дербанить FileGroupDescriptor или FileContents.
Как это делать?
В DataFormats.XXX намеков не вижу, DataFormats.FileDrop в списке отсутствует
...
Рейтинг: 0 / 0
29.06.2016, 03:23
    #39264352
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почтовая программа+Письмо в Inbox+DragDrop
Разобрался, как эта фигня работает.
"Internet Message (rfc822/rfc1522)" -это собственно .eml целиком что мне нужен
"FileGroupDescriptor" -содержит "рекомендуемое" имя файла (Тема_Сообщения.eml) -в API-структуры не вдавался, мне это не нужно

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
  Private Sub Form1_DragEnter(sender As Object, e As DragEventArgs) Handles Me.DragEnter
    If e.Data.GetDataPresent("Internet Message (rfc822/rfc1522)") Then
      e.Effect = DragDropEffects.Copy
    End If
  End Sub

  Private Sub Form1_DragDrop(sender As Object, e As DragEventArgs) Handles Me.DragDrop
    Dim objMemoryStream As IO.MemoryStream = e.Data.GetData("Internet Message (rfc822/rfc1522)", True)
    Dim aFileBytes(0 To objMemoryStream.Length - 1) As Byte
    objMemoryStream.Position = 0
    objMemoryStream.Read(aFileBytes, 0, (objMemoryStream.Length))
    objMemoryStream.Close()

    'если надо получить имя файла как тема_сообщения.eml -нафиг не надо
    Dim aFileGroupArray(512) As Byte
    objMemoryStream = e.Data.GetData("FileGroupDescriptor", True)
    objMemoryStream.Position = 0
    objMemoryStream.Read(aFileGroupArray, 0, 512)
    Dim fileName As System.Text.StringBuilder = New System.Text.StringBuilder(256)
    'following code extracts file name of message
    For intCount = 76 To 512
      fileName.Append(Convert.ToChar(aFileGroupArray(intCount)))
    Next
    objMemoryStream.Close()
    Debug.Print(fileName.ToString)
    '

    'create .eml file
    Dim objFileStream As IO.FileStream = New IO.FileStream("test.eml", IO.FileMode.Create)
    objFileStream.Write(aFileBytes, 0, (aFileBytes.Length))
    objFileStream.Close()
  End Sub



По большому счету и файл .eml на диск сохранять то наверно необязательно.
e.Data.GetData("Internet Message (rfc822/rfc1522)", True) сразу скинуть в ADODB.Stream и в CDO.Message
...
Рейтинг: 0 / 0
29.06.2016, 04:14
    #39264357
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почтовая программа+Письмо в Inbox+DragDrop
А IO.MemoryStream -> ADODB.Stream без промежуточного файла никак?
Хотя б через массив байтов?
Не могу понять как в ADODB.Stream массив байтов загнать вместо Stm.LoadFromFile(Path)

В принципе пофиг, но как-то не очень красиво, писать данные в файл, чтоб потом их оттуда прочесть и файл удалить:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
 Private Sub Form1_DragDrop(sender As Object, e As DragEventArgs) Handles Me.DragDrop
    Dim objMemoryStream As IO.MemoryStream = e.Data.GetData("Internet Message (rfc822/rfc1522)", True)
    Dim aFileBytes(0 To objMemoryStream.Length - 1) As Byte
    objMemoryStream.Position = 0
    objMemoryStream.Read(aFileBytes, 0, (objMemoryStream.Length))
    objMemoryStream.Close()

    'create .eml file
    Dim objFileStream As IO.FileStream = New IO.FileStream("test.eml", IO.FileMode.Create)
    objFileStream.Write(aFileBytes, 0, (aFileBytes.Length))
    objFileStream.Close()

    Dim v_Conf As String = "http://schemas.microsoft.com/cdo/configuration/"
    Dim o_Mess As CDO.Message = LoadMessageFromFile("test.eml") ' As Object
    IO.File.Delete("test.eml")
    With o_Mess.Configuration.Fields
...

  Private Function LoadMessageFromFile(ByVal Path As String) As CDO.Message 'As Object
    Dim iMsg As New CDO.Message '= CreateObject("CDO.Message")

    Dim Stm As New ADODB.Stream '= CreateObject("ADODB.Stream")
    Stm.Open()
    Stm.Type = iMsg.GetStream().Type
    Stm.Charset = iMsg.GetStream().Charset
    Stm.LoadFromFile(Path)
    Dim iDsrc As CDO.IDataSource = iMsg.DataSource ' get IDataSource interface
    iDsrc.OpenObject(Stm, "_Stream")
    LoadMessageFromFile = iMsg
  End Function
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Почтовая программа+Письмо в Inbox+DragDrop / 3 сообщений из 3, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]