/// <summary> /// Creates a new transfer job. /// </summary> /// <param name="displayName">The display name.</param> /// <param name="remoteUrl">The remote URL.</param> /// <param name="localFile">The local file.</param> /// <param name="priority">The priority.</param> /// <exception cref="System.InvalidOperationException">An unexpected exception occurred trying to create the job.</exception> public IDownloadJob CreateJob(string displayName, string remoteUrl, string localFile, DownloadPriority priority = DownloadPriority.Normal) { if (!Path.IsPathRooted(localFile)) { localFile = new FileInfo(localFile).FullName; } var targetDir = Path.GetDirectoryName(localFile); if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } if (File.Exists(localFile)) { File.Delete(localFile); } IBackgroundCopyManager bitsManager = null; IBackgroundCopyJob bitsJob = null; var id = Guid.Empty; try { bitsManager = (IBackgroundCopyManager) new BackgroundCopyManager(); bitsManager.CreateJob(displayName, BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out id, out bitsJob); // *** // SET UP BITS JOB SETTINGS--TIMEOUTS/RETRY ETC // SEE THE FOLLOWING REFERENCES: // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setminimumretrydelay.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setnoprogresstimeout.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/bg_job_priority.asp // *** // in constant set to 0; this makes BITS retry as soon as possible after an error bitsJob.SetMinimumRetryDelay(DownloadJob.DefaultMiniumRetryDelay); // in constant set to 5 seconds; BITS will set job to Error status if exceeded bitsJob.SetNoProgressTimeout(DownloadJob.DefaultNoProgressTimeout); bitsJob.SetPriority((BG_JOB_PRIORITY)(int)priority); bitsJob.AddFile(remoteUrl, localFile); bitsJob.SetNotifyFlags((uint)( BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_ERROR | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_MODIFICATION | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_TRANSFERRED)); var job = new DownloadJob(id, displayName, remoteUrl, localFile, priority); // Set the notify interface to get BITS events bitsJob.SetNotifyInterface(job); return(job); } catch (COMException cex) { string error; bitsManager.GetErrorDescription(cex.ErrorCode, 1033, out error); throw new InvalidOperationException(error, cex); } finally { if (bitsJob != null) { Marshal.ReleaseComObject(bitsJob); } if (bitsManager != null) { Marshal.ReleaseComObject(bitsManager); } } }
/// <summary> /// Asynchronous download method implementation. /// </summary> /// <param name="task">The DownloadTask to process.</param> public void BeginDownload(DownloadTask task) { IBackgroundCopyManager backGroundCopyManager = null; IBackgroundCopyJob backgroundCopyJob = null; Guid jobID = Guid.Empty; try { // create the manager backGroundCopyManager = (IBackgroundCopyManager) new BackgroundCopyManager(); // If the job is already finished, just return if (CheckForResumeAndProceed(backGroundCopyManager, task, out backgroundCopyJob)) { return; } if (backgroundCopyJob != null) { // if CheckForResumeAndProceed connected to an ongoing BITS job // wire up our notify interface to forward events to the client backgroundCopyJob.SetNotifyInterface(this); backgroundCopyJob.SetNotifyFlags((uint)( BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_ERROR | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_MODIFICATION | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_TRANSFERRED) ); } else { // use utility function to create the job. CreateCopyJob( backGroundCopyManager, out backgroundCopyJob, ref jobID, task.DownloadItem.OwnerItemId, task.DownloadItem.Enclosure.Description, task); // Save the jobId in the task task.JobId = jobID; // Prepare the job to download the manifest files PrepareJob(backgroundCopyJob, task); // Set the notify interface to get BITS events backgroundCopyJob.SetNotifyInterface(this); backgroundCopyJob.SetNotifyFlags((uint)( BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_ERROR | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_MODIFICATION | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_TRANSFERRED) ); // Fire our download start event OnDownloadStarted(new TaskEventArgs(task)); // Initiate the BITS Job backgroundCopyJob.Resume(); } } catch (Exception e) { // if exception, clean up job OnJobError(task, backgroundCopyJob, null, e); } finally { if (null != backgroundCopyJob) { Marshal.ReleaseComObject(backgroundCopyJob); } if (null != backGroundCopyManager) { Marshal.ReleaseComObject(backGroundCopyManager); } } }