views:

3576

answers:

4

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.

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.

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!

Thanks!

Rune

+1  A: 

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.

+1  A: 

In your Xaml you need to set up your Event:

<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:

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

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

cgreeno
The FileGroupDescriptor doesn't contain text, just binary data. The resulting strFullString contains nothing readable
Thomas Levesque
I did test the code before I posted it, perhaps you need to change the Encoding?
cgreeno
cgreeno - I forgot to comment that I tried this, but all I get is a bunch of zeroes and somewhere in the middle, the subject of the message. I.e. if I drag a message with the subject "Adresse", I get this: \0\0\0 [etc., a lot of them] Adresse.msg \0\0\0\0\0\0 [a lot more of them].If I remove the \0 characters I can get at the subject, but no sign of where I can find the message body, any attachments, the sender, or other information that is needed.Thanks for trying tho, much appreciated. :)
Rune Jacobsen
+2  A: 

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.

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.

Timo
Thanks, this looks very promising - however, it is based on a WinForms (?) IDataObject, while the IDataObject used in WPF is slightly different. For this to work, I would need a "lossless" way to convert between the two, or...?
Rune Jacobsen
The link is broken...
Thomas Levesque
+5  A: 

I found a great article that 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.

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

In the OutlookDataObject constructor, change

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

Change the SetData implementation from

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.

Bryce Kahle
Thanks - I also found this one and tried to use it, however I am banging my head into the differences between System.Windows.Forms.IDataObject (the one used in Windows Forms and this article) and System.Windows.IDataObject (the one that WPF uses). I don't know nearly enough COM (or whatever that scary looking stuff is) to get this to work, it would seem..!
Rune Jacobsen
I have updated my post to reflect the changes needed to work in WPF.
Bryce Kahle
Thanks again - I am pretty close to this working for me, just have to deal with some exceptions when dragging multiple messages. Congrats on figuring out a difficult one. :)
Rune Jacobsen