title: Drag and Drop large virtual files with IStream using VirtualFileDataObject
body: <p>I am successfully using <a href="http://blogs.msdn.com/b/delay/archive/2009/10/26/creating-something-from-nothing-developer-friendly-virtual-file-implementation-for-net.aspx" rel="nofollow noreferrer">VirtualFileDataObject code from Delay's blog</a>, but i want to avoid streaming the entire file into memory.</p>
  
  <p>I found this previously answered question on Stack Overflow <a href="https://stackoverflow.com/questions/12410114/drag-and-drop-large-virtual-files-from-c-sharp-to-windows-explorer">Drag and Drop large virtual files from c# to Windows Explorer</a>  The question was answered by matthieu, by changing the signature of the SetData method. </p>
  
  <p>Here is my problem, after changing the signature of the SetData method, other places that call it are still looking for the old signature.</p>
  
  <p>Here is the original SetData;</p>
  
  <pre><code>   public void SetData(short dataFormat, int index, Action&lt;Stream&gt; streamData)
      {
          _dataObjects.Add(
              new DataObject
              {
                  FORMATETC = new FORMATETC
                  {
                      cfFormat = dataFormat,
                      ptd = IntPtr.Zero,
                      dwAspect = DVASPECT.DVASPECT_CONTENT,
                      lindex = index,
                      tymed = TYMED.TYMED_ISTREAM
                  },
                  GetData = () =&gt;
                  {
                      // Create IStream for data
                      var ptr = IntPtr.Zero;
                      var iStream = NativeMethods.CreateStreamOnHGlobal(IntPtr.Zero, true);
                      if (streamData != null)
                      {
                          // Wrap in a .NET-friendly Stream and call provided code to fill it
                          using (var stream = new IStreamWrapper(iStream))
                          {
                              streamData(stream);
                          }
                      }
                      // Return an IntPtr for the IStream
                      ptr = Marshal.GetComInterfaceForObject(iStream, typeof(IStream));
                      Marshal.ReleaseComObject(iStream);
                      return new Tuple&lt;IntPtr, int&gt;(ptr, NativeMethods.S_OK);
                  },
              });
      }
  </code></pre>
  
  <p>matthieu suggested to change it to;</p>
  
  <pre><code>public void SetData(short dataFormat, int index, Stream stream)
  {
    ...
    var iStream = new StreamWrapper(stream);
    ...
    // Ensure the following line is commented out:
    //Marshal.ReleaseComObject(iStream);
    return new Tuple&lt;IntPtr, int&gt;(ptr, NativeMethods.S_OK);
   ...
  }
  </code></pre>
  
  <p>After I make these changes the following call will not work; ( and this is where i need help) 
  How do i fix this call;</p>
  
  <pre><code>            foreach (var fileDescriptor in fileDescriptors)
          {
              **SetData(FILECONTENTS, index, fileDescriptor.StreamContents);**
              index++;
          }
  </code></pre>
  
  <p>Basically changing "Action streamData" To "Stream stream" is causing my problems. I am not sure on how to call it after the changes are made.</p>
  
  <p>All this code comes from Delays VirtualFileDataObject.  I don't know if i should post it on here or not.  But if you follow the link above it will take you to the blog so you can view it.</p>
  
  <p>I am so close, just can't figure this last step out, thanks for taking a look</p>