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
Creo que Shell Style Drag and Drop en .NET (WPF y WinForms) puede ayudarte. Una vez que pueda responder a la acción de arrastrar y soltar usando las Interfaces COM, debería poder sacar los datos de outlook.
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).