简体   繁体   English

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

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

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. 我正在使用带有C#的.Net 3.5 Sp1编写的WPF编写的Windows客户端,其中要求客户端收到的电子邮件中的数据可以存储在数据库中。 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. 现在,处理此问题的最简单方法是使用诱导关节炎的量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 符文

I found a great article that should do exactly what you need to. 我找到了一篇很棒的文章 ,应该完全符合你的需要。

UPDATE 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. 很抱歉格式化,但编号/项目符号列表不适用于代码段。

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. 我发现很多解决方案建议您对所有文件名使用“FileGroupDescriptor”,并在DragEventArgs对象上使用“FileContents”来检索每个文件的数据。 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”适用于电子邮件消息名称,但“FileContents”返回null,因为.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上有很好的解释,优秀的示例和代码下载。

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并设置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();
         }


}

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 Assemblies and break the message apart that way. 你的另一个选择是绑定到Outlook MS Office主互操作程序集,并以这种方式打破这些消息。

I think Shell Style Drag and Drop in .NET (WPF and WinForms) can help you. 我认为.NET中的Shell Style Drag and Drop(WPF和WinForms)可以帮到你。 Once you can respond to drag drop using the COM Interfaces, you should be able to get the data out of outlook. 一旦您可以使用COM接口响应拖放,您应该能够从outlook中获取数据。

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 EntryID and StoreID . 您可以做的是从Exchange服务器检索邮件,并根据邮件的EntryIDStoreID将其位置存储在数据库中。 Here's a VB.Net snippet: 这是一个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! 从Outlook检索到电子邮件后,您可以将它们推送到您的数据库中! Save their EntryID and StoreID (you might want to store their parent's (the folder's) EntryID and StoreID as well). 保存他们的EntryIDStoreID (您可能还想存储其父级(文件夹)的EntryIDStoreID )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM