i'm trying to have may application accept attachments dragged in from the Gmail web page.
But when i drag in a attachment , directly from the site e.Data does nor seem to contain the data in any way.
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] dataFormats = e.Data.GetFormats();
Type type = e.Data.GetType();
}
e.Data is of type DataObject. FileDrop, FileNameW, FileName are null DragContext, DragImageBits, chromium/x-renderer-taint are System.IO.MemoryStream
Non of the Memorystream objects hold any file data of the attachment dragged in. Nor any download url.
edit. Apparently when dragging in a picture attachment, the data is holding the URL. but other attachments, does not carry a URL but some way windows explorer knows where to download it when i drag it to desktop, so there must be a way to retrieve this URL.
edit2 added data viewed with 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)}
The attachment is detected as a FileDrop, the data contains the URL to the attachment, which can be retrieved by doing GetData(DataFormats.Text).
Here is some sample code for you to try:
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;
}
}
Note that it is important to handle the DragEnter event and set the e.Effect to DragDropEffects.Copy, otherwise the DragDrop event either won't fire, or won't have the data you need.
The latest Gmail web app has implemented security and now it will not allow you to get direct file url like image. My purpose is to provide you with some explanation on what I did.
I researched some more deep into it and tried some code during debugging in an Immediate window and found that..
There are many Formats available when get the 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"
Then I tried getting Text
format data from it
(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"
So this is nothing but the url to your attachment. When I tried to hit this url on browser directly, I redirected to the attach file. (You must login in browser with google account)
Last I tried the following option
(e.Data as System.Windows.DataObject).GetData("HTML Format");
I got the string with some querystring and html. In the HTML, you can easily find the file name (temporary) and the extension of the file.
The point I want to prove here OR the approach I suggest you is that once you get the URL to the attachment file. You can put a simple web service call / Google API call to the URL and download the file in response.
NOTE: All above mention code is from Visual Studio Immediate window so its a combination of code i executed and output which was returned.
User contributions licensed under CC BY-SA 3.0