Перетащите одно или несколько писем из Outlook в приложение CF WPF - PullRequest
31 голосов
/ 25 ноября 2008

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

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

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

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

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

Спасибо!

Rune

Ответы [ 5 ]

34 голосов
/ 10 июня 2009

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

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);
}

TO

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

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

5 голосов
/ 23 февраля 2009

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

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

3 голосов
/ 25 ноября 2008

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

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

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

private void myTextBlock_Drop(object sender, DragEventArgs e)
{
         // Mark the event as handled, so TextBox's 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, как указано в следующей статье

ваш другой вариант - привязать к перспективам Основные сборки взаимодействия MS Office и таким образом разбить сообщение на части.

1 голос
/ 11 января 2011

Я предполагаю, что у вас есть сервер 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).

1 голос
/ 25 ноября 2008

Я думаю Перетаскивание в стиле оболочки в .NET (WPF и WinForms) может вам помочь. Как только вы сможете реагировать на перетаскивание с помощью COM-интерфейсов, вы сможете получить данные из внешнего вида.

...