Подтвердить что ты не робот

Drag'n'drop одна или несколько писем из приложения Outlook в С# WPF

Я работаю над клиентом Windows, написанным в WPF с С# на .Net 3.5 Sp1, где требование заключается в том, что данные из писем, полученных клиентами, могут храниться в базе данных. В настоящее время самый простой способ справиться с этим - скопировать и вставить текст, тему, информацию о контакте и время, полученные вручную, с использованием величины ctrl-c/ctrl-v, вызывающей артрит.

Я думал, что простой способ справиться с этим - позволить пользователю перетащить одно или несколько писем из Outlook (все они используют Outlook 2007 в настоящее время) в окно, что позволяет моему приложению извлекать необходимую информацию и отправлять ее к серверной системе для хранения.

Тем не менее, несколько часов поискового запроса информации об этом, похоже, указывают на шокирующее отсутствие информации об этой, казалось бы, основной задаче. Я бы подумал, что что-то вроде этого будет полезно в самых разных настройках, но все, что мне удалось найти, - это полупеченные не-решения.

Есть ли у кого-нибудь советы о том, как это сделать? Поскольку я просто собираюсь читать письма и не посылать ничего или делать что-либо злое, было бы неплохо с решением, которое не включало бы ненавистные всплывающие всплывающие окна безопасности, но что-либо бьется, не имея возможности сделать это вообще.

В принципе, если бы я мог получить список всех почтовых элементов, которые были выбраны, перетаскиваемые из Outlook, я сам смогу справиться с остальными!

Спасибо!

руна

4b9b3361

Ответ 1

Я нашел отличную статью которая должна делать именно то, что вам нужно.

UPDATE

Мне удалось получить код в этой статье, работающий в WPF с небольшой настройкой, ниже приведены изменения, которые вам нужно сделать.

Измените все ссылки из System.Windows.Forms.IDataObject на System.Windows.IDataObject

В конструкторе OutlookDataObject измените

FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);

Для

FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("_innerData", BindingFlags.NonPublic | BindingFlags.Instance);

Измените все вызовы DataFormats.GetFormat на DataFormats.GetDataFormat

Измените реализацию SetData из

public void SetData(string format, bool autoConvert, object data)
{
    this.underlyingDataObject.SetData(format, autoConvert, data);
}

К

public void SetData(string format, object data, bool autoConvert)
{
    this.underlyingDataObject.SetData(format, data, autoConvert);
}

С этими изменениями я смог получить это, чтобы сохранить сообщения в файлах, как это сделала статья. Извините за форматирование, но нумерованные/маркированные списки не очень хорошо работают с фрагментами кода.

Ответ 2

Я нашел много решений, предлагающих использовать "FileGroupDescriptor" для всех имен файлов и "FileContents" объекта DragEventArgs для извлечения данных каждого файла. "FileGroupDescriptor" отлично работает для имен сообщений электронной почты, но "FileContents" возвращает нуль, поскольку реализация IDataObject в .NET не может обрабатывать объект IStorage, который возвращается COM.

У Дэвида Эвена есть отличное объяснение, отличная загрузка кода и кода, которая отлично работает на http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx.

Ответ 3

В вашем Xaml вам нужно настроить свое событие:

<TextBlock
        Name="myTextBlock"  
        Text="Drag something into here"
        AllowDrop="True" 
        DragDrop.Drop="myTextBlock_Drop"
        />

После того, как вы установили AllowDrop = True и установите событие drop, перейдите к коду и настройте свое событие:

private void myTextBlock_Drop(object sender, DragEventArgs e)
{
         // Mark the event as handled, so TextBox native Drop handler is not called.
         e.Handled = true;
         Stream sr;

          //Explorer 
          if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
              //Do somthing

        //Email Message Subject 
        if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            sr = e.Data.GetData("FileGroupDescriptor") as Stream;
                StreamReader sr = new StreamReader(sr2);//new StreamReader(strPath, Encoding.Default);
            //Message Subject
                    string strFullString = sr.ReadToEnd();
         }


}

Если вы хотите разбить его дальше, вы можете использовать: FILEDESCRIPTOR или FILECONTENTS в следующем виде статья

ваш другой вариант - связать в Outlook MS Office Primary Interop Assemblies и разбить сообщение таким образом.

Ответ 4

Я думаю, Shell Style Drag and Drop в .NET(WPF и WinForms) может вам помочь. Как только вы сможете ответить на перетаскивание с помощью COM-интерфейсов, вы сможете получить данные из Outlook.

Ответ 5

Я предполагаю, что у вас есть сервер Exchange, работающий за Outlook.

Что вы можете сделать, так это получить почту с сервера Exchange и сохранить ее местоположение в базе данных на основе почтовых EntryID и StoreID. Вот фрагмент VB.Net:

Imports Microsoft.Office.Interop

Public Class OutlookClientHandler

Private _application As Outlook.Application
Private _namespace As Outlook.NameSpace

Public Sub New()
    If Process.GetProcessesByName("outlook".ToLower).Length > 0 Then
        _application = New Outlook.Application
    Else
        Dim startInfo As ProcessStartInfo = New ProcessStartInfo("outlook.exe")
        startInfo.WindowStyle = ProcessWindowStyle.Minimized
        Process.Start(startInfo)

        _application = New Outlook.Application
    End If
End Sub

' Retrieves the specified e-mail from Outlook/Exchange via the MAPI
Public Function GetMailItem(ByVal entryID as String, ByVal storeID as String) As Outlook.MailItem
    _namespace = _application.GetNamespace("MAPI")
    Dim item As Outlook.MailItem
    Try
        item = _namespace.GetItemFromID(entryID, storeID)
    Catch comex As COMException
        item = Nothing ' Fugly, e-mail wasn't found!
    End Try

    Return item
End Function
End Class

Я думаю, вам удобно использовать MAPI, иначе вы можете прочитать здесь: http://msdn.microsoft.com/en-us/library/cc765775(v=office.12).aspx

Чтобы получить выбранные сообщения электронной почты из Outlook:

Public Function GetSelectedItems() As List(Of Object) 
    Dim items As List(Of Object) = New List(Of Object)

    For Each item As Object In _application.ActiveExplorer().Selection
        items.Add(item)
    Next

    Return items
End Function

После того, как вы получили электронные письма из Outlook, вы можете просто вставить их в свою базу данных! Сохраните их EntryID и StoreID (вы можете захотеть сохранить их родительский (папка) EntryID и StoreID, а также).