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; }
/// <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> /// 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; } } }