17

Google Chrome has a handy feature where I can click a download link and drag it into a Windows Explorer window, and then drop. After dropping, Chrome then downloads the file and it appears where I dropped it.

I would like to be able to drop from Google Chrome into my application, but it seems it isn't so simple. I have a DataGridView called gridFiles, and the following code:

Private Sub gridFiles_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles gridFiles.DragDrop
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
        Dim DroppedFiles() As String = e.Data.GetData(DataFormats.FileDrop)
        If Not DroppedFiles Is Nothing Then
            For Each file As String In DroppedFiles
                MsgBox(file)
            Next
        End If
    End If
End Sub

Private Sub gridFiles_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles gridFiles.DragEnter
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
        e.Effect = DragDropEffects.All
    End If

End Sub

When I drop files onto it from Windows Explorer, all works fine and I get a message box for each file that was dropped. However, when I drop from Chrome, nothing happens. The reason for this is that DroppedFiles is equal to Nothing. It seems that e.Data.GetData isn't returning anything. I have checked the formats with e.Data.GetFormats() and it returns FileDrop, FileName, FileNameW as expected with any file drop.

What I am quite sure is happening is that Chrome says it has some files so that the DragEnter functions, but since it hasn't downloaded the file yet, DragDrop cannot be done, so Chrome returns no files. I suspect that in a Windows Explorer context, Chrome somehow gets that window's path and copies the file there itself later.

So my question is...

How can I fool Google Chrome into dropping into my application? I see this working by somehow giving Chrome a temporary folder where it thinks it has dropped the file, and my application would monitor that folder for new files and pull them in once they are downloaded. I just need to find a way for Chrome to "know" that folder.

Alternatively, if I could get the URL of what was dropped, that would be just fine as well. I could then download the file with my program.

Any and all advice is much appreciated. Thanks.


EDIT: So it seems that with regular URLs, I do get the proper dragged-in UniformResourceLocator format. The behavior I am seeing occurs with the download links in Gmail. It probably happens elsewhere, but I am not sure. When a gmail attachment is dragged from Gmail into my application, I get a FileDrop.

Doing some more digging, it seems that Gmail is using the download_url attribute of the anchor tag. I have never heard of this before. Perhaps this is just an extra property they have added?

In any case, since my application will primarily be used with e-mail attachments, I need a way for the phantom FileDrop to work, as stated above. I am unable to use Spy++. It doesn't seem to show any messages when drops occur. (I welcome any advice on that problem as well.)

Edit #2: Here is more information on how Gmail utilizes drag/drop for files: http://www.thecssninja.com/javascript/gmail-dragout

Brad
  • 159,648
  • 54
  • 349
  • 530
  • _if I could get the URL..._ is limitated to pemalink urls – Saic Siquot May 27 '11 at 20:14
  • @Luis, what do you mean? – Brad May 27 '11 at 20:16
  • on some downloads (not peRmalink urls) your app won't have the necesary session state (cookies) to have access to the desired file. – Saic Siquot May 27 '11 at 20:34
  • @Luis, I understand what you are saying now. Yes, having Chrome do the downloading is my first preference, but downloading the file later (even if that means only handling URLs that don't require login/session) is acceptable for my application as well. – Brad May 27 '11 at 20:49
  • 1
    Instead of relying on `DataFormats.FileDrop` you might want to check which values are returned by `e.Data.GetFormats()`. Doing some quick tests it looks like the format `"UniformResourceLocator"` (or even `"Text"`) makes `e.Data.Get(...)` return a `MemoryStream` that contains the URL to the dragged link in plain text. Maybe this is something to investigate further. – jCoder May 27 '11 at 22:55
  • @jCoder, as mentioned in my post, it returns `FileDrop`, `FileName`, and `FileNameW`. I haven't seen `UniformResourceLocator` or `Text`, unfortunately. – Brad May 28 '11 at 01:32
  • I have tried to do it, and I don't have the same formats as you have, with Chrome or IE. I do have url-styles formats, and not FileDrop events. Could you post a piece of code to reproduce? Are you sure there is no addon on 3rd party download utility which is doing things under the surface? – Simon Mourier May 28 '11 at 06:54
  • @Brad I tried it on two computers (XP, Win7), both from Chrome 11.0.696.71 (the most recent version for me) and I always got `Text` and `UniformResourceLocator`. Actually my test app was build using C# but that should not make any difference, does it? – jCoder May 28 '11 at 11:43
  • Very weird. The code above is copied directly out of my program. Perhaps it depends on the type of resource being linked to? I have been testing with download links in Gmail. I will experiment some more with more links. – Brad May 28 '11 at 14:15
  • I'm new to programming , I got you that link http://msdn.microsoft.com/en-us/library/aa984430%28v=vs.71%29.aspx wish it helps you – Ahmed Ghoneim May 29 '11 at 15:44
  • @jCoder, see my latest edit. Turns out that I do get `UniformResourceLocator` with "regular" URLs. The trouble I am having is with a specific kind of download drag/drop, that only seems to be available within Gmail. I'd imagine other sites are using it as well, but so far, Gmail file attachments is where I see this behavior. – Brad May 31 '11 at 15:18
  • @Brad - I have tested GMail "download" link, and I do have FileDrop,FileName & FileNameW formats that all contain an array of strings. This array contains just 1 string with a local filename. The file format is something like "d:\Users\Simon\AppData\Local\Temp\chrome32083\mytestfile.txt". BTW, I'm using Chrome version 11.0.696.71. Also make sure the target application where you drop file is not running as administrator (or check all this disabling with UAC disabled on your system), because this has implication on D&D operations. – Simon Mourier Jun 03 '11 at 10:07
  • @Brad - did you get this working? I'm trying to do exactly the same thing. I have been looking at all these posts for 2 days but i cant get it working! – WraithNath Jan 10 '17 at 17:14
  • @WraithNath No, this never worked properly for me. It's a shame that Google doesn't implement standard stuff for the OS it's using. This used to work fine back in Internet Explorer. – Brad Jan 10 '17 at 19:41
  • @Brad - thanks for the reply, its a shame as it must be possible, it works great dragging to the desktop. Ill spend one more day on it then its going to have to be unsupported! – WraithNath Jan 10 '17 at 21:21
  • 1
    @WraithNath You might have a look at the Chromium source code. That might provide more answers. – Brad Jan 10 '17 at 21:29

3 Answers3

4

I've pulled kilometers of hair out of my head myself regarding weird drag-drop behaviour. Spy++ as mentioned by sixlettervariables might be a good idea. Another would be to take a look at the discussion from one of my Q/As here at SO:

Drag and Drop between Instances of the same Windows Forms Application

From my own experience I seem to remember that drag/drop from a browser is a security issue and thus handled differently. Hope this helps.

EDIT:

Maybe this answers your question:

http://www.vbforums.com/showthread.php?t=529211

Community
  • 1
  • 1
Pedery
  • 3,632
  • 1
  • 27
  • 39
  • Any advice on getting Spy++ working? I can't get it to show any drag/drop messages. – Brad May 31 '11 at 15:20
  • Sorry, I just know I had similar issues and found browser-stuff to be very restricted. If you figure this out, I'll be implementing a version of it in one of my own apps :) – Pedery Jun 01 '11 at 03:12
  • unfortunately, it doesn't look like I am going to figure this one out, heh. Only 2 days left on the +100 bounty, and I don't even know where to begin to track this one down. The only idea I can think of is to actually put some explorer component on my form, but that is less than ideal. I'm not even sure it would work. – Brad Jun 01 '11 at 13:50
  • I edited my answer. Maybe the solution in the link works for you. – Pedery Jun 03 '11 at 05:35
2

Have you considered using Spy++ to see what messages are sent from Chrome to Windows Explorer? Spy++ has message logging which has helped me in the past with strange behavior. You can enable logging of WM_DROPFILES, etc.

user7116
  • 63,008
  • 17
  • 141
  • 172
  • Yes, I used Spy++ but didn't see any messages, until after the drop, and then it was just MOUSEMOVE and what not. (In fact, I was just posting a separate question regarding that!) I will go back and see if there is a filter or something enabled. – Brad May 27 '11 at 19:20
  • I can't get Spy++64/32 to generate the WM_DROPFILES message either, but I'm on a 64bit machine which may just complicate things. – user7116 May 27 '11 at 19:30
2

Strangely, I only get shortcuts when dragging files from Chrome.

Anyway, in case Chrome does the drag & drop with virtual sources, that is, it downloads the file and generates the content on drag & drop completion, you have to implement shell interface IDropTarget. I get the feeling the file contents might be transferred via IStream which is not supported by .NET Drag&Drop.

Maybe this http://msdn.microsoft.com/en-us/library/bb776904%28VS.85%29.aspx#copying and this Drag and drop virtual files using IStream should get you on the right path.

Community
  • 1
  • 1
Arunas
  • 918
  • 1
  • 8
  • 20