1

When dragging items from Outlook email into a Winforms app (Control is a GalleryControl by DevExpress, the DragDrop event is not firing, even though i manually set 'DragDropEffects.Move` in the DragEnter event handler. (have confirmed that this is firing)

However DragDrop event does fire just when dragging normal files from windows explorer.

    private async void gcImages_DragDrop(object sender, DragEventArgs e)
    {

        string[] fileNames = null;

        if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
        {
            fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
        }
        else if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            OutlookDataObject dataObject = new OutlookDataObject(e.Data);
            string[] filenames = (string[])dataObject.GetData("FileGroupDescriptor");
        }
        // do stuff async with file names
    }

    private void gcImages_DragEnter(object sender, DragEventArgs e)
    {
        // This event fires, no matter what i drag onto it.  (Files from explorer, attachments from Outlook etc)  
        // However even after setting the effect as per below, the cursor still shows the 'not allowed' symbol.
        e.Effect = DragDropEffects.Move;
    }

I have enabled AllowDrop = true on the control, and it works perfectly with Windows Explorer files, just not outlook files.

The strange thing is that the DragEnter event is firing, but the DragDrop event does not fire with Outlook attachments.

Brendan Gooden
  • 1,460
  • 2
  • 21
  • 40
  • 1
    You may be running into the limitation that Lower-privileged processes cannot drag-and-drop to higher-privileged applications. – TheGeneral Feb 18 '20 at 05:43
  • Cannot replicate, using different types of Users (Outlook 2016/x64). The object contains an array of `FILEDESCRIPTORW` structures. The first byte of the MemoryStream contains the number of structures. The structures return the file names of the attachments, while the `FileContents` format returns a MemoryStream containing the attachments bytes. Drag & Droppen on a standard WinForms control. Try with a non-DevExpress control, with different User privileges, to test what works in your context. – Jimi Feb 18 '20 at 06:34
  • managed to get it to work with Outlook 2019, was using 2013? Any idea why this would be? – Brendan Gooden Feb 19 '20 at 03:14

1 Answers1

1

Ended up using this code, seemed to work fine.

//// Use Like This

    private void gcImages_DragDrop(object sender, DragEventArgs e)
    {
        DragDropHelper.AcceptDroppedFile(e, AddAndSaveNewDocument);
    }

    private void AddAndSaveNewDocument(FileSystemInfo fileInfo)
    {

    }


////


public static class DragDropHelper
{
    public static void AcceptDroppedFile(DragEventArgs e, Action<FileInfo> addAndSaveNewDocument)
    {
        string[] fileNames = null;

        if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
        {
            fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
        }
        else if (e.Data.GetDataPresent("FileGroupDescriptor"))
        {
            var dataObject = new OutlookDataObject(e.Data);
            fileNames = (string[])dataObject.GetData("FileGroupDescriptor");

            for (var i = 0; i < fileNames.Length; i++)
            {
                var itm = fileNames[i];
                using var ms = dataObject.GetData("FileContents", i);

                var tmpFileName = Path.Combine(Path.GetTempPath(), itm);

                using (var file = new FileStream(tmpFileName, FileMode.Create, System.IO.FileAccess.Write))
                {
                    byte[] bytes = new byte[ms.Length];
                    ms.Read(bytes, 0, (int)ms.Length);
                    file.Write(bytes, 0, bytes.Length);
                    ms.Close();
                }

                fileNames[i] = tmpFileName;
            }
        }
        if (fileNames != null)
        {
            foreach (var fileName in fileNames)
            {
                var fileInfo = new FileInfo(fileName);

                addAndSaveNewDocument(fileInfo);

                if (fileName.Contains(Path.GetTempPath(), StringComparison.CurrentCultureIgnoreCase))
                {
                    File.Delete(fileName);
                }
            }
        }
    }
}

Code here for OutlookDataObject class https://codeshare.io/G7747D

Brendan Gooden
  • 1,460
  • 2
  • 21
  • 40