public void GetData(ref FORMATETC format, out STGMEDIUM medium) { medium = new STGMEDIUM(); if (format.dwAspect != DVASPECT.DVASPECT_CONTENT) { Marshal.ThrowExceptionForHR(DV_E_DVASPECT); } if (format.cfFormat == CF_AMAZON_DRIVE_ITEMS) { var mem = new MemoryStream(); var bf = new BinaryFormatter(); bf.Serialize(mem, baseItems); mem.Position = 0; medium.tymed = TYMED.TYMED_ISTREAM; medium.unionmember = Marshal.GetComInterfaceForObject(new StreamWrapper(mem), typeof(IStream)); medium.pUnkForRelease = null; } else if (format.cfFormat == CF_FILEDESCRIPTORW) { var hGlobal = Marshal.AllocHGlobal(fileGroupDescriptorBuffer.Length); Marshal.Copy(fileGroupDescriptorBuffer, 0, hGlobal, fileGroupDescriptorBuffer.Length); medium.tymed = TYMED.TYMED_HGLOBAL; medium.unionmember = hGlobal; medium.pUnkForRelease = null; } else if (format.cfFormat == CF_FILECONTENTS) { if (format.lindex >= 0 && format.lindex < selectedItems.Length) { driveStream?.Dispose(); driveStream = new AmazonDriveBaseStream(DriveData.Drive, selectedItems[format.lindex]); medium.tymed = TYMED.TYMED_ISTREAM; medium.unionmember = Marshal.GetComInterfaceForObject(new StreamWrapper(driveStream), typeof(IStream)); medium.pUnkForRelease = null; } else { Marshal.ThrowExceptionForHR(DV_E_TYMED); } } else { Marshal.ThrowExceptionForHR(DV_E_TYMED); } }
private void button_Start_Click(object sender, EventArgs e) { if (SelectedRemoteFiles == null) { return; } button_Start.Enabled = false; var synchronizationContext = SynchronizationContext.Current; var masterjob = JobControler.CreateNewJob(JobControler.JobClass.Normal); masterjob.DisplayName = "Download test"; masterjob.ProgressStr = "wait for download"; runningjob = masterjob; var joblist = new ConcurrentBag <JobControler.Job>(); Parallel.ForEach(SelectedRemoteFiles, (item) => { var job = JobControler.CreateNewJob(JobControler.JobClass.Download, depends: masterjob); job.WeekDepend = true; job.DisplayName = DriveData.GetFullPathfromId(item.id); job.ProgressStr = "Wait for download"; joblist.Add(job); var ct = CancellationTokenSource.CreateLinkedTokenSource(masterjob.ct, job.ct).Token; JobControler.Run(job, (j) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "download..."; }, null); (j as JobControler.Job).ProgressStr = "download..."; var retry = 5; while (--retry > 0) { ct.ThrowIfCancellationRequested(); try { long length = item.contentProperties.size ?? 0; using (var ret = new AmazonDriveBaseStream(DriveData.Drive, item, autodecrypt: false, parentJob: (j as JobControler.Job))) using (var f = new PositionStream(ret, length)) { f.PosChangeEvent += (src, evnt) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var eo = o as PositionChangeEventArgs; var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = eo.Log; }, evnt); (j as JobControler.Job).ProgressStr = evnt.Log; (j as JobControler.Job).Progress = (double)evnt.Position / evnt.Length; }; f.CopyTo(new NullStream()); } synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Done"; }, null); (j as JobControler.Job).ProgressStr = "Done."; (j as JobControler.Job).Progress = 1; break; } catch (OperationCanceledException) { throw; } catch (Exception ex) { Config.Log.LogOut("Download : Error " + ex.Message); continue; } } if (retry == 0) { // failed synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Failed"; }, null); (j as JobControler.Job).ProgressStr = "Failed"; (j as JobControler.Job).Progress = double.NaN; (j as JobControler.Job).IsError = true; } }); }); JobControler.Run(masterjob, (j) => { masterjob.ProgressStr = "running..."; masterjob.Progress = -1; var ct = (j as JobControler.Job).ct; Task.WaitAll(joblist.Select(x => x.WaitTask(ct: ct)).ToArray()); masterjob.Progress = 1; masterjob.ProgressStr = "done."; }); var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: masterjob); afterjob.DisplayName = "clean up"; afterjob.DoAlways = true; JobControler.Run(afterjob, (j) => { afterjob.ProgressStr = "done."; afterjob.Progress = 1; runningjob = null; synchronizationContext.Post((o) => { button_Start.Enabled = true; }, null); }); }
override public void EndOperation(uint hResult, IBindCtx pbcReserved, uint dwEffects) { base.EndOperation(hResult, pbcReserved, dwEffects); driveStream?.Dispose(); driveStream = null; }