11
votes

I've created a basic Custom Task Pane in Outlook.

I want to drag an email and drop it into the task pane. When dropped, it should allow me to capture the email as an object I guess, allowing me to do stuff with it, as in save to a sharepoint location for example.

Is that possible? If so, any pointers?

I am using VS2013 C# .NET 4.0 and Add-in is for Outlook 2010/2013.

3
What do you mean by "to do stuff with it"? Is it enough to access the mail message as a raw .msg file? (filename and contents as raw bytes)Dávid Molnár

3 Answers

5
votes

Prerequisites and Setup

  • Windows 10 Pro
  • Visual Studio 2013 Ultimate with Office development
  • Outlook 2013 with an email account

Project

  • In Visual Studio select New Project -> Visual C# -> Office/SharePoint -> Office Add-ins -> Outlook 2013 Add-in
  • Right click on the project -> Add -> User Control
  • Open "ThisAddIn.cs" and add the following code to the "ThisAddIn_Startup" method:

    var myCustomPane= this.CustomTaskPanes.Add(new UserControl1(), "My Pane");
    myCustomPane.Visible = true;
    

Outlook 2013 Custom Pane

Drag and Drop messages

  • Double click UserControl1 in the Solution Explorer. This opens the designer window.
  • In Properties set AllowDrop = True and hook up two event handlers DragDrop and DragEnter.

    private void UserControl1_DragEnter(object sender, DragEventArgs e)
    {
        // if you want to read the message data as a string use this:
        if (e.Data.GetDataPresent(DataFormats.UnicodeText))
        {
            e.Effect = DragDropEffects.Copy;
        }
        // if you want to read the whole .msg file use this:
        if (e.Data.GetDataPresent("FileGroupDescriptorW") && 
            e.Data.GetDataPresent("FileContents"))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }
    
    private void UserControl1_DragDrop(object sender, DragEventArgs e)
    {
        // to read basic info about the mail use this:
        var text = e.Data.GetData(DataFormats.UnicodeText).ToString();
        var message = text.Split(new string[] { "\r\n" }, StringSplitOptions.None)[1];
        var parts = message.Split('\t');
        var from = parts[0]; // Email From
        var subject = parts[1]; // Email Subject
        var time = parts[2]; // Email Time
    
        // to get the .msg file contents use this:
        // credits to "George Vovos", http://stackoverflow.com/a/43577490/1093508
        var outlookFile = e.Data.GetData("FileGroupDescriptor", true) as MemoryStream;
        if (outlookFile != null)
        {
            var dataObject = new iwantedue.Windows.Forms.OutlookDataObject(e.Data);
    
            var filenames = (string[])dataObject.GetData("FileGroupDescriptorW");
            var filestreams = (MemoryStream[])dataObject.GetData("FileContents");
    
            for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
            {
                string filename = filenames[fileIndex];
                MemoryStream filestream = filestreams[fileIndex];
    
                // do whatever you want with filestream, e.g. save to a file:
                string path = Path.GetTempPath() + filename;
                using (var outputStream = File.Create(path))
                {
                    filestream.WriteTo(outputStream);
                }
            }
        }
    }
    

You can get "iwantedue.Windows.Forms.OutlookDataObject" from CodeProject or you can use this GitHub gist.

Demo

Outlook 2013 Custom Pane Drag and drop email message

0
votes

You can get the dropped item or multiple items (if allowed) by checking the Selection property of the Explorer class. Read more about that in the following articles:

0
votes

Try something like this

        public static string[] GetDropedFiles(DragEventArgs e)
        {
            string[] files = null;
            var outlookFile = e.Data.GetData("FileGroupDescriptor", true) as MemoryStream;
            if (outlookFile != null)
            {
                OutlookEmailObject dataObject = new OutlookEmailObject(e.Data);

                var filenames = (string[])dataObject.GetData("FileGroupDescriptorW");
                var filestreams = (MemoryStream[])dataObject.GetData("FileContents");

                files = new string[filenames.Length];
                for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
                {
                    string filename = filenames[fileIndex];
                    MemoryStream filestream = filestreams[fileIndex];

                    string path = Path.GetTempPath();
                    string fullFileName = path + filename;

                    FileStream outputStream = File.Create(fullFileName);
                    filestream.WriteTo(outputStream);
                    outputStream.Close();

                    files[fileIndex] = fullFileName;
                }
            }
            else
                files = (string[])e.Data.GetData(DataFormats.FileDrop);

            return files;
        }

You can get the OutlookEmailObject class here (Download the code sample):
http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C

(Of course you should delete all the temp files after you are done will them)