我正在研究使用C#在.Net 3.5 Sp1上用WPF编写的Windows客户端,其中要求客户端接收的电子邮件中的数据可以存储在数据库中。现在,处理此问题的最简单方法是使用关节炎诱导量ctrl-c / ctrl-v复制并粘贴手动接收的文本,主题,联系信息和时间。
我认为处理这种情况的一种简单方法是允许用户将一个或多个电子邮件从Outlook(他们都使用当前的Outlook 2007)拖到窗口中,允许我的应用程序提取必要的信息并发送给它到后端系统进行存储。
但是,几个小时的谷歌搜索信息似乎表明这个看似基本的任务令人震惊的缺乏信息。我认为这样的东西在许多不同的设置中会有用,但到目前为止我能找到的所有东西都是半生不熟的非解决方案。
有没有人对如何做到这一点有任何建议?因为我只是要阅读邮件而不是发送任何内容或做任何有害的事情,所以对于一个不涉及讨厌的安全弹出窗口的解决方案会很好,但是任何事情都无法完成。< / p>
基本上,如果我能够获得所有选中的邮件列表,从Outlook中拖放,我将能够自己处理其余邮件!
谢谢!
符文
答案 0 :(得分:34)
我找到了一个很棒的article,它应该完全符合你的需要。
<强>更新强>
我能够通过一些调整获得该文章中的代码在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);
}
通过这些更改,我能够像文章那样将消息保存到文件中。很抱歉格式化,但编号/项目符号列表不适用于代码段。
答案 1 :(得分: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上运行良好。
答案 2 :(得分: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'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在以下article
中列出你的另一个选择是与观点MS Office Primary Interop Assemblies联系起来,并以这种方式打破这个消息。
答案 3 :(得分:1)
我认为Shell Style Drag and Drop in .NET (WPF and WinForms)可以帮到你。一旦您可以使用COM接口响应拖放,您应该能够从Outlook中获取数据。
答案 4 :(得分:1)
我假设您在Outlook后面运行Exchange服务器。
您可以做的是从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
)。