繁体   English   中英

将Gmail附件拖到C#Winform

[英]Drag Gmail attachment to c# winform

我正在尝试让应用程序接受从Gmail网页拖入的附件。

但是,当我直接从站点中拖动附件时,e.Data似乎也没有以任何方式包含数据。

    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        string[] dataFormats = e.Data.GetFormats();
        Type type = e.Data.GetType();
    }

e.Data是DataObject类型。 FileDrop,FileNameW,FileName为null DragContext,DragImageBits,chromium / x-renderer-taint为System.IO.MemoryStream

Memorystream对象中的任何一个都不包含所拖动附件的任何文件数据。也不包含任何下载URL。

编辑。 显然,当拖动图片附件时,数据将包含URL。 但是其他附件不包含URL,但是当我将其拖动到桌面时,Windows Explorer会以某种方式知道将其下载到何处,因此必须有一种检索此URL的方法。

edit2添加了使用即时窗口查看的数据对象的数据

    (e.Data as System.Windows.DataObject).GetFormats(false);
{string[4]}
    [0]: "DragContext"
    [1]: "DragImageBits"
    [2]: "chromium/x-renderer-taint"
    [3]: "FileDrop"
(e.Data as System.Windows.DataObject).GetData("DragContext");
'(e.Data as System.Windows.DataObject).GetData("DragContext")' threw an exception of type 'System.Runtime.InteropServices.COMException'
    Data: {System.Collections.ListDictionaryInternal}
    ErrorCode: -2147221404
    HResult: -2147221404
    HelpLink: null
    InnerException: null
    Message: "Invalid FORMATETC structure (Exception from HRESULT: 0x80040064 (DV_E_FORMATETC))"
    Source: "System"
    StackTrace: "   at System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)\r\n   at System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)\r\n   at System.Windows.DataObject.OleConverter.GetDataFromOleHGLOBAL(String format, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetDataFromBoundOleDataObject(String format, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)\r\n   at System.Windows.DataObject.GetData(String format, Boolean autoConvert)\r\n   at System.Windows.DataObject.GetData(String format)"
    TargetSite: {Void GetData(System.Runtime.InteropServices.ComTypes.FORMATETC ByRef, System.Runtime.InteropServices.ComTypes.STGMEDIUM ByRef)}
(e.Data as System.Windows.DataObject).GetData("DragImageBits");
{System.IO.MemoryStream}
    CanRead: true
    CanSeek: true
    CanTimeout: false
    CanWrite: true
    Capacity: 87144
    Length: 87144
    Position: 0
    ReadTimeout: '((System.IO.Stream)(e.Data as System.Windows.DataObject).GetData("DragImageBits")).ReadTimeout' threw an exception of type 'System.InvalidOperationException'
    WriteTimeout: '((System.IO.Stream)(e.Data as System.Windows.DataObject).GetData("DragImageBits")).WriteTimeout' threw an exception of type 'System.InvalidOperationException'
(e.Data as System.Windows.DataObject).GetData("chromium/x-renderer-taint");
{System.IO.MemoryStream}
    CanRead: true
    CanSeek: true
    CanTimeout: false
    CanWrite: true
    Capacity: 1
    Length: 1
    Position: 0
    ReadTimeout: '((System.IO.Stream)(e.Data as System.Windows.DataObject).GetData("chromium/x-renderer-taint")).ReadTimeout' threw an exception of type 'System.InvalidOperationException'
    WriteTimeout: '((System.IO.Stream)(e.Data as System.Windows.DataObject).GetData("chromium/x-renderer-taint")).WriteTimeout' threw an exception of type 'System.InvalidOperationException'
(e.Data as System.Windows.DataObject).GetData("FileDrop");
'(e.Data as System.Windows.DataObject).GetData("FileDrop")' threw an exception of type 'System.Runtime.InteropServices.COMException'
    Data: {System.Collections.ListDictionaryInternal}
    ErrorCode: -2147221404
    HResult: -2147221404
    HelpLink: null
    InnerException: null
    Message: "Invalid FORMATETC structure (Exception from HRESULT: 0x80040064 (DV_E_FORMATETC))"
    Source: "System"
    StackTrace: "   at System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)\r\n   at System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)\r\n   at System.Windows.DataObject.OleConverter.GetDataFromOleHGLOBAL(String format, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetDataFromBoundOleDataObject(String format, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)\r\n   at System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)\r\n   at System.Windows.DataObject.GetData(String format, Boolean autoConvert)\r\n   at System.Windows.DataObject.GetData(String format)"
    TargetSite: {Void GetData(System.Runtime.InteropServices.ComTypes.FORMATETC ByRef, System.Runtime.InteropServices.ComTypes.STGMEDIUM ByRef)}

将附件检测为FileDrop,数据包含附件的URL,可以通过执行GetData(DataFormats.Text)来检索该附件。

这是一些示例代码供您尝试:

private void Form1_DragDrop(object sender, DragEventArgs e) {
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
    if (files == null) {
        string url = (string)e.Data.GetData(DataFormats.Text);
        MessageBox.Show(url);
   }
}

private void Form1_DragEnter(object sender, DragEventArgs e) {
    if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
        e.Effect = DragDropEffects.Copy;
    }
}

请注意,处理DragEnter事件并将e.Effect设置为DragDropEffects.Copy非常重要,否则DragDrop事件将不会触发,或者将无法获得所需的数据。

最新的Gmail网络应用已实现了安全性,现在不允许您获取直接的文件网址(如图片)。 我的目的是为您提供一些有关我所做的解释。

我对其进行了更深入的研究,并在“即时”窗口的调试过程中尝试了一些代码,然后发现了。

获取DataObject时有许多可用的格式

(e.Data as System.Windows.DataObject).GetFormats(false);

{string[13]}
        [0]: "DragContext"
        [1]: "DragImageBits"
        [2]: "chromium/x-renderer-taint"
        [3]: "FileDrop"
        [4]: "UnicodeText"
        [5]: "Text"
        [6]: "text/x-moz-url"
        [7]: "FileGroupDescriptorW"
        [8]: "FileContents"
        [9]: "UniformResourceLocatorW"
        [10]: "UniformResourceLocator"
        [11]: "HTML Format"
        [12]: "text/html"

然后我尝试从中获取Text格式数据

(e.Data as System.Windows.DataObject).GetDataPresent("Text");
true

(e.Data as System.Windows.DataObject).GetData("Text");
    "https://mail.google.com/mail/u/0/?ui=X&ik=XXXXXXXXXXX&view=att&th=XXXXXXXXXX&attid=0.1&disp=inline&safe=1&zw"

因此,这不过是您附件的网址。 当我尝试直接在浏览器中访问此URL时,我重定向到了附件。 (您必须使用Google帐户登录浏览器)

最后我尝试了以下选项

(e.Data as System.Windows.DataObject).GetData("HTML Format");

我得到了带有一些querystring和html的字符串。 在HTML中,您可以轻松找到文件名(临时)和文件扩展名。

我想在这里证明这一点或我建议您采用的方法是,一旦获得附件文件的URL。 您可以在URL上放置一个简单的Web服务调用/ Google API调用,然后作为响应下载文件。

注意:所有上述代码均来自Visual Studio即时窗口,因此它是我执行的代码和返回的输出的组合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM