c# wpf outlook drag-and-drop

Arrastra y suelta uno o más correos desde Outlook a la aplicación C#WPF



drag-and-drop (5)

Estoy trabajando en un cliente de Windows escrito en WPF con C # en .Net 3.5 Sp1, donde el requisito es que los datos de los correos electrónicos recibidos por los clientes se puedan almacenar en la base de datos. En este momento, la manera más fácil de manejar esto es copiar y pegar el texto, el tema, la información de contacto y el tiempo recibido manualmente usando una cantidad inductora de artritis de ctrl-c / ctrl-v.

Pensé que una forma sencilla de manejar esto sería permitir al usuario arrastrar uno o más correos desde Outlook (todos usan Outlook 2007 actualmente) en la ventana, lo que permite que mi aplicación extraiga la información necesaria y la envíe al servidor. sistema de almacenamiento.

Sin embargo, unas pocas horas buscando en Google información sobre esto parecen indicar una sorprendente falta de información sobre esta tarea aparentemente básica. Pensaría que algo como esto sería útil en muchos entornos diferentes, pero todo lo que he podido encontrar hasta ahora han sido soluciones poco sofisticadas.

¿Alguien tiene algún consejo sobre cómo hacer esto? Como solo voy a leer los correos y no enviaré nada ni haré nada malo, sería bueno tener una solución que no incluyera las ventanas emergentes de seguridad, pero todo vale más que no poder hacerlo.

Básicamente, si pudiera obtener una lista de todos los elementos de correo que fueron seleccionados, arrastrados y soltados desde Outlook, ¡podré manejar el resto yo mismo!

¡Gracias!

Runa



En tu Xaml necesitas configurar tu evento:

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

Una vez que tienes Set AllowDrop = True y Set you drop event, ve al código que está detrás y configura tu evento:

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

Si desea dividirlo aún más, puede usar: FILEDESCRIPTOR o FILECONTENTS como se describe en el siguiente artículo

su otra opción es vincular las vistas de las Asambleas primarias de interoperabilidad de MS Office y dividir el mensaje de esa manera.


Encontré un excelente artículo que debería hacer exactamente lo que necesita.

ACTUALIZAR

Pude obtener el código en ese artículo trabajando en WPF con un pequeño ajuste, a continuación se detallan los cambios que debe realizar.

Cambie todas las referencias de System.Windows.Forms.IDataObject a System.Windows.IDataObject

En el constructor OutlookDataObject, cambie

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

A

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

Cambiar todas las llamadas de DataFormats.GetFormat a DataFormats.GetDataFormat

Cambia la implementación de SetData de

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

A

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

Con esos cambios, pude conseguir que guardara los mensajes en archivos como lo hizo el artículo. Perdón por el formato, pero las listas numeradas / con viñetas no funcionan bien con los fragmentos de código.


Encontré muchas soluciones que sugerían usar el "FileGroupDescriptor" para todos los nombres de archivo y el "FileContents" en el objeto DragEventArgs para recuperar los datos de cada archivo. El "FileGroupDescriptor" funciona bien para los nombres de los mensajes de correo electrónico, pero "FileContents" devuelve un valor nulo porque la implementación de IDataObject en .Net no puede manejar el objeto IStorage que devuelve COM.

David Ewen tiene una gran explicación, excelente muestra y descarga de código que funciona muy bien en http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx .


Supongo que tiene un servidor de Exchange ejecutándose detrás de Outlook.

Lo que puede hacer es recuperar el correo del servidor de Exchange y almacenar su ubicación en su base de datos en función de EntryID y StoreID del correo. Aquí hay un fragmento de 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

Supongo que se siente cómodo con el uso de MAPI; de lo contrario, puede leer aquí: http://msdn.microsoft.com/en-us/library/cc765775(v=office.12).aspx

Para recuperar los correos electrónicos seleccionados de 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

¡Después de que haya recuperado los correos electrónicos de Outlook, puede simplemente insertarlos en su base de datos! Guarde su EntryID y StoreID (es posible que desee almacenar el StoreID sus padres (el de la carpeta) y el StoreID también).