我正试图让应用程序接受从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资源管理器知道在哪里下载它,所以必须有一种方法来检索这个URL。
edit2添加了使用Immediate Window for DataObject查看的数据
(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");
我得到了一些查询字符串和HTML的字符串。在HTML中,您可以轻松找到文件名(临时)和文件的扩展名。
我想在这里证明一点,或者我建议你的方法是,一旦你得到附件文件的URL。您可以对URL进行简单的Web服务调用/ Google API调用,然后下载该文件作为响应。
注意:所有上面提到的代码都来自Visual Studio立即窗口,因此它是我执行的代码和返回的输出的组合。