![](/img/trans.png)
[英]drag and drop rasterImageviewer in winform applications (c#)
[英]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.