32

我正在使用 .Net 3.5 Sp1 上的 C# 用 WPF 编写的 Windows 客户端,其中的要求是客户端收到的电子邮件中的数据可以存储在数据库中。现在最简单的处理方法是复制和粘贴文本、主题、联系信息和手动接收的时间,使用引起关节炎的量 ctrl-c/ctrl-v。

我认为处理此问题的一种简单方法是允许用户将一封或多封电子邮件从 Outlook(它们目前都使用 Outlook 2007)拖到窗口中,允许我的应用程序提取必要的信息并将其发送到后端存储系统。

然而,在谷歌上搜索这方面的信息几个小时似乎表明关于这个看似基本的任务的信息令人震惊地缺乏。我认为这样的事情在很多不同的环境中都会很有用,但到目前为止我所能找到的只是半生不熟的非解决方案。

有人对如何做到这一点有任何建议吗?因为我只是要阅读邮件而不是发送任何东西或做任何邪恶的事情,所以最好有一个不涉及讨厌的安全弹出窗口的解决方案,但任何事情都胜过根本无法做到这一点。

基本上,如果我能获得所有从 Outlook 中选择、拖放的邮件项目的列表,我将能够自己处理其余的!

谢谢!

符文

4

5 回答 5

37

我找到了一篇很棒的文章,它应该完全符合您的需要。

更新

稍作调整,我就可以让那篇文章中的代码在 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);
}

通过这些更改,我能够像文章一样将消息保存到文件中。抱歉格式化,但编号/项目符号列表不适用于代码片段。

于 2009-06-09T22:42:47.280 回答
5

我发现很多解决方案建议您对所有文件名使用“FileGroupDescriptor”,并在 DragEventArgs 对象上使用“FileContents”来检索每个文件的数据。“FileGroupDescriptor”适用于电子邮件名称,但“FileContents”返回 null,因为 .Net 中的 IDataObject 实现无法处理 COM 返回的 IStorage 对象。

David Ewen 在http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx上有很好的解释、出色的示例和代码下载,效果很好。

于 2009-02-23T09:55:51.300 回答
3

在您的 Xaml 中,您需要设置您的事件:

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

一旦您设置了 AllowDrop = True 并设置您放置事件,然后转到后面的代码并设置您的事件:

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 作为以下文章中的概述

您的另一个选择是绑定到 Outlook MS Office Primary Interop Assemblies并以这种方式分解消息。

于 2008-11-25T16:43:16.720 回答
1

我认为.NET(WPF 和 WinForms)中的 Shell 样式拖放可以为您提供帮助。一旦您可以使用 COM 接口响应拖放,您应该能够从 Outlook 中获取数据。

于 2008-11-25T16:16:26.370 回答
1

我假设您有一个在 Outlook 后面运行的 Exchange 服务器。

您可以做的是从 Exchange 服务器检索邮件并根据邮件的EntryIDStoreID. 这是一个 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 检索电子邮件后,您可以将它们推送到您的数据库中!保存他们的EntryIDand StoreID(您可能还想存储他们父级的(文件夹的)EntryIDand StoreID)。

于 2011-01-11T09:46:52.867 回答