Search code examples
c#vb.netwinapicomc++-cli

Using COM to copy virtual files to Explorer from .net


I am trying to use IStream in VB.NET to copy virtual files to Windows Explorer using a wrapper class that chains calls to my own IO.Stream implementation.

I am using my own implementation of IDataObject to transfer data to Explorer using CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS.

Everything seems to work fine (even with >1GB files), except the target Windows Explorer window stops responding until the operation completes.

The answer here - CFSTR_FILEDESCRIPTOR/CFSTR_FILECONTENTS 'Copying Files' Dialog missing doesn't help.

My IDataObject Implementation is based on https://svn.cyberduck.io/tags/release-4-0/source/ch/cyberduck/core/VirtualFileDataObject.cs

The difference is, instead of loading the entire virtual file into memory before copying, I set CFSTR_FILECONTENTS to a pointer to an implemetation of IStream with this function:

Public Sub Read(pv() As Byte, cb As Integer, pcbRead As IntPtr) Implements IStream.Read
    Marshal.WriteInt64(pcbRead, 0, stream.Read(pv, 0, cb))
End Sub

Clarification: I am trying to transfer a file from my application to Windows Explorer and not the other way around.

Any help would be much appreciated.

Sorry for my English.


Solution

  • You can implement the IDataObjectAsyncCapability interface to allow Explorer to extract the data asynchronously.

    See Dragging and Dropping Shell Objects Aynchronously for a description of how it works. The steps that the drop source needs to take to run asynchronously are:

    1. Create a data object that exposes IAsyncOperation/IDataObjectAsyncCapability.
    2. Call SetAsyncMode with fDoOpAsync set to VARIANT_TRUE to indicate that an asynchronous operation is supported.
    3. After DoDragDrop returns, call InOperation:
      • If InOperation fails or returns VARIANT_FALSE, a normal synchronous data transfer has taken place and the data extraction process is finished. The source should do any cleanup that is required, and proceed.
      • If InOperation returns VARIANT_TRUE, the data is being extracted asynchronously. Cleanup operations should be handled by EndOperation.
    4. Release the data object.
    5. When the asynchronous data transfer is complete, the data object normally notifies the source through a private interface.