如何从未保存在磁盘上的拖放文件中获取数据

3

如何读取未保存在磁盘上的xml文件内容?

我想能够从Outlook拖动附件(文件扩展名是自定义的)并将其放入我的应用程序中。根据xml文件的内容,我将相应地执行一些操作。

我尝试通过e.Data.GetFormats()GetData(format)进行迭代,但没有成功。我尝试过e.Data.GetData("FileContents"),但不起作用。我还尝试了e.Data.GetData(DataFormat.Text),以及DataFormats.UnicodeTextDataFormats.FileDrop等,都无法正常工作。

从中读取文件的内容很重要,因为我不想强制用户在拖动之前保存文件。

非常感谢任何帮助!

答案

对于那些有同样问题的人来说,这是格式良好的答案:

因此,从磁盘上保存的任何文件被拖放时都会具有可以加载和读取的完整路径。

从Outlook拖放的任何文件都将具有“FileGroupDesciptor”,以获取带有其扩展名的文件名。 "FileContents"将包含内容的数据流。

示例:

处理拖放文件以查看是否可以执行某些操作

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;
                break;
          
            default:
                itemType = DropItemType.None;
                break;

        }
        canHandleDropData = (itemType != DropItemType.None);
    }
    
    if (canHandleDropData)
        e.Effect = DragDropEffects.Copy;
}

获取拖放文件的内容

 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);
            doc.LoadXml(xmlString);
        }
        else
        {
            //outlook file content
            var xmlString = rawContent as MemoryStream;
            doc.Load(xmlString);    
        }

        return doc;
    }
1个回答

1

这是我使用的代码,可以处理从Windows资源管理器或Outlook附件转换为内存流的文件。(ms是表单上的公共MemoryStream变量)。我相信您可以使用相同的逻辑将其转换为字符串读取器。

      Private Sub ubFilepath_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ubFilepath.DragDrop
    Try
        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
            Try
                thestream.Read(fileGroupDescriptor, 0, 700)
                Dim i As Integer = 76
                While fileGroupDescriptor(i) <> 0
                    filename.Append(Convert.ToChar(fileGroupDescriptor(i)))
                    i += 1
                End While
                Me.ubFilepath.Text = "Outlook attachment_" + filename.ToString
                ms = e.Data.GetData("FileContents", True)
            Finally
                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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接