Creating something from nothing - and knowing it [Developer-friendly virtual file implementation for .NET refined!]
**
This blog has moved to a new location and comments have been disabled.
All old posts, new posts, and comments can be found on The blog of dlaa.me.
See you there!
Comments
Anonymous
November 24, 2009
Hi! Thanks for this interested article! I have a question. How could I drop an empty folder with your code?Anonymous
November 25, 2009
iop111, That's a great question - I honestly had no idea at first! But I've got good news. :) Firstly, if you just want to put the virtual file(s) in a subdirectory, you can use the code I've posted just like it is. To see this in action, just change the string "Alphabet.txt" to "Dir\Alphabet.txt" in the sample and you'll see a "Dir" directory get created in the folder you drop to with an "Alphabet.txt" file inside it. You can even specify different directories for different virtual files in the same drag-drop operation! So that probably covers what you want 99% of the time. The remaining 1% is if you want the drop to create an empty directory. If that's your goal, I don't think the virtual file technique shown here will help because the documentation doesn't seem to say anything about creating a directory (everything deals with files). But creating a directory is (pretty much always) a synchronous operation, so if that's your goal, you should be able to create the directory somewhere temporary and then use the standard DROPFILES/SetFileDropList technique to let Windows do the work of creating it in the right place for you. Thanks for the question - hope this helps you out!Anonymous
May 25, 2010
Great implimentation but there are still a few bugs in the class. In windows 7 when explorer calls the GetData method it gives a value for dwAspect of DVASPECT_TUMBNAIL | DVASPECT_CONTENT. Need to change any comparison statements with FORMATETC.dwAspect to allow for multiple values like the FORMATETC.tymed statements do. Also I am trying to use an ISTREAM to transfer virtual files to windows explorer. However, the implimentation uses a wrapper that writes all of the data to the ISTREAM object when SetData(...) is called. My application has a large amount of files to copy and some that are 1gb+ in size. Using this implimentation I can not copy files larger then my physical memory. I need to somehow impliment the IStream COM interface but allocate it in unmanaged space so that other programs can gain access to it. Also need to solve the memory problem.Anonymous
May 25, 2010
You can drag and drop empty folder by adding them to the FileDescriptor setting the Contents to an empty stream and settings FileDescriptor.Attributes = FILE_ATTRIBUTE_DIRECTORY; Make sure to set the size to zero. Some external applications when dropped onto will call FILE_CONTENTS if they do you return an empty STREAM. Sorry I dont have the code anymore because it is proprietary and I no longer have access to it.Anonymous
May 25, 2010
Ken Parker, That's great information, thanks so much for sharing! Regarding the dwAspect issue, what you say makes total sense. However, because I developed this code on Windows 7 and ran it successfully, I think it's not ALWAYS the case that THUMBNAIL is OR-ed in or I would have seen this myself. Of course, that's no excuse - I'm just explaining why I didn't do so in the first place. :) I get your point about the IStream memory limitation. If you come up with any suggestions for things I might do differently that wouldn't overly complicate the common "small file" case, I'd love to hear them. The folder handling information is cool - that scenario wasn't on my radar when I wrote this code. Thanks again! I've added some notes to my TODO list to follow up on your comments when I get a chance.Anonymous
May 25, 2010
I dont know why it is OR-ed with THUMBNAIL maybe depends on the current view of the folder. I do believe it was working at one point with out that correction but not sure what caused the mistake. So you may not be getting it now but it my creep up on you laterAnonymous
May 25, 2010
The current implimentation converts a .NET Stream to a COM IStream. It uses an unmanaged call to allocate the memory. I think the solution is to impliment the COM IStream interface in managed code so that the file does not have to remain in memory to be transferred. The problem I run into is I dont know enough about COM interop to marshal this into the correct Memory so that external apps like Windows Explorer or MS Outlook can read the address when it calls GetData expecting a pointer to the IStream interface.Anonymous
October 14, 2010
Hi! Thanks for your work! Great! When I drop a file from my App to the explorer it always has a length of 0 bytes. When I copy the same file via the clipboard it works! Any idea? What does Ken mean with changing FORMATETC.dwAspect? Can you update the sample? Thanks a lot!!!!!!Anonymous
October 14, 2010
After some tests I found out that asynchron modus is the problem! I changed this: void IAsyncOperation.GetAsyncMode(out int pfIsOpAsync) { //pfIsOpAsync = IsAsynchronous ? NativeMethods.VARIANT_TRUE : NativeMethods.VARIANT_FALSE; pfIsOpAsync = NativeMethods.VARIANT_FALSE; } Then it works! Any idea why asynchron modus does not work?Anonymous
October 15, 2010
Pro, As I recall, the sample works for your scenario, so I'm wondering if maybe the problem you're seeing has to do with something you're doing a little differently. Offhand, I'm not sure what that would be, but I recall things being very picky about exactly how they were configured. If you agree the sample seems to work okay, you might start by trying to identify the differences vs. your implementation. Alternatively, gradually turn the sample into your implementation and see when it breaks. :)Anonymous
October 17, 2010
Hi! Thanks for your answer! I found the problem! It was the start action! The start action called a method to show the wait screen. But invoking the UI thread caused a very weird deadlock. I don't know why this happen but it definitly causes the problem :-(Anonymous
October 18, 2010
Pro, That is weird - but I'm glad to hear you found the problem! Thanks for letting me know!Anonymous
March 12, 2012
The comment has been removedAnonymous
March 12, 2012
Tim Dellas, It sounds like maybe something's not working well with your system - Windows Explorer shouldn't crash no matter what my sample tries to do. (And it doesn't crash for other folks who have successfully used this code.) FYI that the sample application already does what you ask for - please have a look at the method TextUrlVirtualFile_MouseButtonDown to see how it asynchronously downloads a file to the drop location (with a busy indicator).Anonymous
May 24, 2012
Hi David! Thank you very much for this piece of code ! I'm still trying to figure out how everything work (inside), but it work well :) Do you now how I can retrieve the dropped file path ? I really like the way you handle download of file, but my case is a bit more complicated. So what I'm tring to do is, drag and drop a file with only its FileDescriptor information, and retrieve its location once windows created an empty file, and then handle myself the download in my application. For now I managed to drop a file, it is created by windows, but no way to retrieve its path, and more than that each time I try another drag and drop, windows keeps dropping the first one. It's like the first d&d operation never ended.Anonymous
May 26, 2012
Basile Cornet, Based on my understanding of your question, the following two links may be helpful: social.msdn.microsoft.com/.../454470ac-a9ea-4e1b-a341-b32672d56495 stackoverflow.com/.../drag-drop-from-form-to-windows-get-drop-destination However, the complete answer may be that it's not possible to do this in general which is what Raymond Chen seems to suggest here: blogs.msdn.com/.../2453927.aspx Hope this helps!Anonymous
May 28, 2012
Hi David, Thank you for your answer. We may have to change how we handle drag and drop, if I rely on the post by Raymond Chen. Thank you.Anonymous
December 20, 2012
Great explanation and example of Drag source! Would highly appreciate to see C# code working as Drop Target with your demo application for Virtual File. Thanks again.Anonymous
December 20, 2012
Alex Nossov, Thanks - I'll keep that in mind if I ever update this sample in the future!