将一封或多封邮件从 Outlook 拖放到 C# WPF 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/316900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 22:57:01  来源:igfitidea点击:

Drag'n'drop one or more mails from Outlook to C# WPF application

c#wpfoutlookdrag-and-drop

提问by Rune Jacobsen

I'm working on a windows client written in WPF with C# on .Net 3.5 Sp1, where a requirement is that data from emails received by clients can be stored in the database. Right now the easiest way to handle this is to copy and paste the text, subject, contact information and time received manually using an arthritis-inducing amount of ctrl-c/ctrl-v.

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

I thought that a simple way to handle this would be to allow the user to drag one or more emails from Outlook (they are all using Outlook 2007 currently) into the window, allowing my app to extract the necessary information and send it to the backend system for storage.

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

However, a few hours googling for information on this seem to indicate a shocking lack of information about this seemingly basic task. I would think that something like this would be useful in a lot of different settings, but all I've been able to find so far have been half-baked non-solutions.

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

Does anyone have any advice on how to do this? Since I am just going to read the mails and not send anything out or do anything evil, it would be nice with a solution that didn't involve the hated security pop ups, but anything beats not being able to do it at all.

有没有人对如何做到这一点有任何建议?由于我只是要阅读邮件而不是发送任何内容或做任何邪恶的事情,因此如果有一个不涉及讨厌的安全弹出窗口的解决方案会很好,但任何事情都比根本无法做到。

Basically, if I could get a list of all the mail items that were selected, dragged and dropped from Outlook, I will be able to handle the rest myself!

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

Thanks!

谢谢!

Rune

符文

采纳答案by Bryce Kahle

I found a great articlethat should do exactly what you need to.

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

UPDATE

更新

I was able to get the code in that article working in WPF with a little tweaking, below are the changes you need to make.

通过稍加调整,我能够使那篇文章中的代码在 WPF 中工作,以下是您需要进行的更改。

Change all references from System.Windows.Forms.IDataObject to System.Windows.IDataObject

将所有引用从 System.Windows.Forms.IDataObject 更改为 System.Windows.IDataObject

In the OutlookDataObject constructor, change

在 OutlookDataObject 构造函数中,更改

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

To

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

Change all DataFormats.GetFormat calls to DataFormats.GetDataFormat

将所有 DataFormats.GetFormat 调用更改为 DataFormats.GetDataFormat

Change the SetData implementation from

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

With those changes, I was able to get it to save the messages to files as the article did. Sorry for the formatting, but numbered/bulleted lists don't work well with code snippets.

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

回答by Rune Jacobsen

I think Shell Style Drag and Drop in .NET (WPF and WinForms)can help you. Once you can respond to drag drop using the COM Interfaces, you should be able to get the data out of outlook.

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

回答by cgreeno

In your Xaml you need to set up your Event:

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

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

Once you have Set AllowDrop = True and Set you drop event then go to the code behind and set up your event:

一旦您设置了 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();
         }


}

If you wish to break it down further you can use: FILEDESCRIPTOR or FILECONTENTS as outline in the following article

如果您想进一步分解它,您可以使用:FILEDESCRIPTOR 或 FILECONTENTS 作为以下文章中的大纲

your other option is to tie into outlooks MS Office Primary Interop Assembliesand break the message apart that way.

您的另一个选择是将 Outlook 与MS Office 主要互操作程序集联系起来,并以这种方式将消息分开。

回答by Timo

I found a lot of solutions suggesting you use the “FileGroupDescriptor” for all the file names and the “FileContents” on the DragEventArgs object to retrieve the data of each file. The “FileGroupDescriptor” works fine for the email message names, but “FileContents” returns a null because the implementation of the IDataObject in .Net cannot handle the IStorage object that is returned by COM.

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

David Ewen has a great explanation, excellent sample and code download that works great at http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx.

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

回答by Zolomon

I assume that you have an Exchange server running behind Outlook.

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

What you can do is to retrieve the mail from the Exchange server and store its location in your database based on the mail's EntryIDand StoreID. Here's a VB.Net snippet:

你可以做的是检索从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

I guess you are comfortable with using the MAPI, otherwise you can read up here: http://msdn.microsoft.com/en-us/library/cc765775(v=office.12).aspx

我想您对使用 MAPI 很满意,否则您可以在这里阅读:http: //msdn.microsoft.com/en-us/library/cc765775(v=office.12).aspx

To retrieve the selected e-mails from outlook:

要从 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

After you've retrieved the e-mails from Outlook you can just push them into your database! Save their EntryIDand StoreID(you might want to store their parent's (the folder's) EntryIDand StoreIDas well).

从 Outlook 检索电子邮件后,您可以将它们推送到您的数据库中!保存他们的EntryIDStoreID(您可能还想存储他们的父级(文件夹的)EntryIDStoreID)。