How to get data from Drag 'n Dropdown file that is not saved to disk

How can I read the xml content of an xml file that is not saved anywhere on disk?

I want to be able to drag and drop an attachment from Outlook (file extension is the usual one) and leave it in my application. Based on the content of the xml file, I will take the appropriate action.

I have tried iterating through e.Data.GetFormats()

and GetData(format)

to no avail. I tried e.Data.GetData("FileContents")

didn't work. I tried e.Data.GetData(DataFormat.Text)

also DataFormats.UnicodeText

, DataFormats.FileDrop

and nothing works.

It's important to read the contents of the file from DataObject

, as I don't want to force the user to save the file before dragging and dropping it.

Any help would be greatly appreciated!


Well-formatted answer for those who have the same question:

This way, any file saved to the discarded disk will have a full path that can be loaded and read.

Any file deleted from Outlook will have a "FileGroupDesciptor" to get the filename along with its extension. "FileContents" will contain the content stream.


Process dragged files to see if we can do some action

public void DragEnter(DragEventArgs e)
    var obj = e.Data as DataObject;

    //get fileName of file saved on disk
    var fileNames = obj.GetFileDropList();

    if(fileNames.Count > 0)
        fileName = fileNames[0]; //I want only one at a time

    //Get fileName not save on disk
    if (string.IsNullOrEmpty(fileName) && obj.GetDataPresent("FileGroupDescriptor"))
        var ms = (MemoryStream)obj.GetData("FileGroupDescriptor");
        ms.Position = 76;
        char a;
        while ((a = (char)ms.ReadByte()) != 0)
            fileName += a;

    if (fileName.Length != 0)
        var extension = fileName.Substring(fileName.LastIndexOf('.') + 1);
        switch (extension.ToUpper())
            case "WTV":
                itemType = DropItemType.WTVFile;

                itemType = DropItemType.None;

        canHandleDropData = (itemType != DropItemType.None);

    if (canHandleDropData)
        e.Effect = DragDropEffects.Copy;


Get the contents of the dragged file

 public XmlDocument GetXmlDocument(DragEventArgs dragEventArgs)
        var doc = new XmlDocument();

        //Get content of outlook file not saved on disk
        var rawContent = dragEventArgs.Data.GetData("FileContents");

        if (rawContent == null)
           //if null then it is a saved file and I can read its content by loading file name
            var xmlString = File.ReadAllText(fileName);
            //outlook file content
            var xmlString = rawContent as MemoryStream;

        return doc;



source to share

1 answer

This is the code I am using that converts files from Windows Explorer or attachments from Appearance to Memory Stream. (ms is the public memory stream variable in the form). I'm sure you can use the same logic to convert it to a string reader.

      Private Sub ubFilepath_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ubFilepath.DragDrop
        If e.Data.GetDataPresent(DataFormats.Text) Then
            Me.ubFilepath.Text = e.Data.GetData("Text")
        ElseIf e.Data.GetDataPresent(DataFormats.FileDrop) Then
            Dim fileNames() As String
            Dim MyFilename As String
            fileNames = DirectCast(e.Data.GetData(DataFormats.FileDrop), String())
            MyFilename = fileNames(0)
            Me.ubFilepath.Text = MyFilename

        //RenPrivateItem is from outlook

        ElseIf e.Data.GetDataPresent("RenPrivateItem") Then
            Dim thestream As System.IO.MemoryStream = e.Data.GetData("FileGroupDescriptor")
            Dim filename As New System.Text.StringBuilder("")
            Dim fileGroupDescriptor(700) As Byte
                thestream.Read(fileGroupDescriptor, 0, 700)
                Dim i As Integer = 76
                While fileGroupDescriptor(i) <> 0
                    i += 1
                End While
                Me.ubFilepath.Text = "Outlook attachment_" + filename.ToString
                ms = e.Data.GetData("FileContents", True)
                If thestream IsNot Nothing Then thestream.Close()
            End Try
        End If
    Catch ex As Exception
        MessageBox.Show(ex.ToString, "Only files can be dragged into this box")
    End Try




All Articles