void IBackgroundCopyCallback.JobError(IBackgroundCopyJob bitsJob, IBackgroundCopyError error) { try { // if the error hasn't been reported, try to get it if (error == null) { bitsJob.GetError(out error); } } catch (COMException) { } // If we've got the native error, extract values and populate the // status message. if (error != null) { StatusMessage = FormatError(error); } BG_JOB_STATE state; bitsJob.GetState(out state); if (state != BG_JOB_STATE.BG_JOB_STATE_ACKNOWLEDGED && state != BG_JOB_STATE.BG_JOB_STATE_CANCELLED) { bitsJob.Cancel(); } Status = DownloadStatus.Error; }
public void Cancel() { //Possible Errors //BG_S_UNABLE_TO_DELETE_FILES Job was successfully canceled; however, the service was unable to delete the temporary files associated with the job. //BG_E_INVALID_STATE Cannot cancel a job whose state is BG_JOB_STATE_CANCELLED or BG_JOB_STATE_ACKNOWLEDGED. copyJob.Cancel(); }
/// <summary> /// Centralizes all chores related to stopping and cancelling a copy job, and getting back /// from BITS the errors incurred during the job. /// </summary> /// <param name="task">reference to the job associated task</param> /// <param name="pJob">reference to the copy job object (not job id)</param> /// <param name="pError">reference to the COM error reported by bits (might be null)</param> /// <param name="ex">reference to an exception cosidered as an error (might be null)</param> private void OnJobError(DownloadTask task, IBackgroundCopyJob pJob, IBackgroundCopyError pError, Exception ex) { Exception finalException = ex; if (pJob != null) { // get information about this job string jobDesc; pJob.GetDescription(out jobDesc); string jobName; pJob.GetDisplayName(out jobName); Guid jobID; pJob.GetId(out jobID); try { // if the error hasn't been reported, try to get it if (pError == null) { pJob.GetError(out pError); } } catch (COMException e) { Logger.Error(e); if (e.ErrorCode != ExceptionCodeNotAnError) { throw; } } // If we've got the native error, wrap into a nicer exception if (pError != null) { var BitsEx = new BitsDownloadErrorException(pError, (uint)CultureIdForGettingComErrorMessages); cumulativeErrorMessage += BitsEx.Message + Environment.NewLine; finalException = BitsEx; } BG_JOB_STATE state; pJob.GetState(out state); if (state != BG_JOB_STATE.BG_JOB_STATE_ACKNOWLEDGED && state != BG_JOB_STATE.BG_JOB_STATE_CANCELLED) { pJob.Cancel(); } RemoveCopyJobEntry(jobID); } OnDownloadError(new DownloadTaskErrorEventArgs(task, finalException)); Logger.Error(finalException); //throw finalException; }
/// <summary> /// Centralizes all chores related to stopping and cancelling a copy job, and getting back /// from BITS the errors incurred during the job. /// </summary> /// <param name="copyJob">reference to the copy job object (not job id)</param> /// <param name="errMessage">a cumulative error message passed by reference so /// that additions can be made</param> private void HandleDownloadErrorCancelJob( IBackgroundCopyJob copyJob, ref string errMessage) { string singleError = ""; string jobDesc = ""; string jobName = ""; Guid jobID = Guid.Empty; IBackgroundCopyError copyError = null; try { // check if job is null; don't try to clean up null references! if (null != copyJob) { // get information about this job for reporting the error copyJob.GetDescription(out jobDesc); copyJob.GetDisplayName(out jobName); copyJob.GetId(out jobID); // find out what the error was copyJob.GetError(out copyError); // use the culture id specified in RESX to tell COM which culture to return err message in: copyError.GetErrorDescription((uint)CULTURE_ID_FOR_COM, out singleError); // add error to our "stack" of errors: errMessage += singleError + Environment.NewLine; // notify BITS that we consider this job a loss, forget about it: copyJob.Cancel(); // remove job from collection RemoveCopyJobEntry(jobID); // log error, but don't throw here; let dnldmgr take care of error // NOTE that errMessage is used cumulatively for full track of problem errMessage = ApplicationUpdateManager.TraceWrite("[BITSDownloader]", "RES_EXCEPTION_BITSBackgroundCopyError", jobID, jobName, jobDesc, errMessage); ExceptionManager.Publish(new Exception(errMessage)); } } finally { if (null != copyError) { Marshal.ReleaseComObject(copyError); copyError = null; } } }
/// <summary> /// cancel the job /// </summary> public void Cancel() { CheckError(delegate { try { _job.Cancel(); } finally { _progressWatch.Stop(); } }); }
/// <summary> /// Cancels an asynhronous download operation. /// </summary> /// <param name="task">The <see cref="DownloadTask"/> for the operation.</param> /// <returns>Indicates whether the operation was canceled.</returns> public bool CancelDownload(DownloadTask task) { IBackgroundCopyManager copyManager = null; IBackgroundCopyJob pJob = null; if (task.JobId != null) { try { Guid jobID = task.JobId.Value; copyManager = (IBackgroundCopyManager) new BackgroundCopyManager(); copyManager.GetJob(ref jobID, out pJob); if (pJob != null) { pJob.Cancel(); } } catch (COMException) { /* we may come up empty when trying to get the job */ } finally { if (copyManager != null) { Marshal.ReleaseComObject(copyManager); } if (pJob != null) { Marshal.ReleaseComObject(pJob); } } } return(true); }
/// <summary> /// used by externally visible overload. /// </summary> /// <param name="isDisposing">whether or not to clean up managed + unmanaged/large (true) or just unmanaged(false)</param> private void Dispose(bool isDisposing) { const uint BG_JOB_ENUM_CURRENT_USER = 0; // const uint BG_JOB_ENUM_ALL_USERS = 0x0001; leads to ACCESS DENIED errors IBackgroundCopyManager mgr = null; IEnumBackgroundCopyJobs jobs = null; IBackgroundCopyJob job = null; if (isDisposing) { try { mgr = (IBackgroundCopyManager)(new BackgroundCopyManager()); mgr.EnumJobs(BG_JOB_ENUM_CURRENT_USER, out jobs); uint numJobs; jobs.GetCount(out numJobs); // lock the jobs collection for duration of this operation lock (bitsDownloaderJobs.SyncRoot) { for (int i = 0; i < numJobs; i++) { // use jobs interface to walk through getting each job uint fetched; jobs.Next(1, out job, out fetched); // get jobid guid Guid jobID; job.GetId(out jobID); // check if the job is in OUR collection; if so cancel it. we obviously don't want to get // jobs from other Updater threads/processes, or other BITS jobs on the machine! if (bitsDownloaderJobs.Contains(jobID)) { // take ownership just in case, and cancel() it job.TakeOwnership(); job.Cancel(); // remove from our collection bitsDownloaderJobs.Remove(jobID); } } } } finally { if (null != mgr) { Marshal.ReleaseComObject(mgr); mgr = null; } if (null != jobs) { Marshal.ReleaseComObject(jobs); jobs = null; } if (null != job) { Marshal.ReleaseComObject(job); job = null; } } } }
/// <summary> /// Centralizes all chores related to stopping and cancelling a copy job, and getting back /// from BITS the errors incurred during the job. /// </summary> /// <param name="copyJob">reference to the copy job object (not job id)</param> /// <param name="errMessage">a cumulative error message passed by reference so /// that additions can be made</param> private void HandleDownloadErrorCancelJob( IBackgroundCopyJob copyJob, ref string errMessage) { string singleError = ""; string jobDesc = ""; string jobName = ""; Guid jobID = Guid.Empty; IBackgroundCopyError copyError = null; try { // check if job is null; don't try to clean up null references! if( null != copyJob ) { // get information about this job for reporting the error copyJob.GetDescription( out jobDesc ); copyJob.GetDisplayName( out jobName ); copyJob.GetId( out jobID ); // find out what the error was copyJob.GetError( out copyError ); // use the culture id specified in RESX to tell COM which culture to return err message in: copyError.GetErrorDescription( (uint)CULTURE_ID_FOR_COM, out singleError ); // add error to our "stack" of errors: errMessage += singleError + Environment.NewLine; // notify BITS that we consider this job a loss, forget about it: copyJob.Cancel(); // remove job from collection RemoveCopyJobEntry( jobID ); // log error, but don't throw here; let dnldmgr take care of error // NOTE that errMessage is used cumulatively for full track of problem errMessage = ApplicationUpdateManager.TraceWrite( "[BITSDownloader]", "RES_EXCEPTION_BITSBackgroundCopyError", jobID, jobName, jobDesc, errMessage ); ExceptionManager.Publish( new Exception( errMessage ) ); } } finally { if( null != copyError ) { Marshal.ReleaseComObject( copyError ); copyError = null; } } }
internal void CancelJob() { _job.Cancel(); }