Пример #1
0
        internal DownloadJob(Guid id, IBackgroundCopyJob bitsJob)
        {
            this.id = id;

            string name;

            bitsJob.GetDisplayName(out name);
            DisplayName = name;

            string description;

            bitsJob.GetDescription(out description);
            Description = description;

            BG_JOB_PRIORITY priority;

            bitsJob.GetPriority(out priority);
            Priority = (DownloadPriority)(int)priority;

            bitsJob.GetMinimumRetryDelay(out minimumRetryDelay);
            bitsJob.GetNoProgressTimeout(out noProgressTimeout);

            BG_JOB_STATE state;

            bitsJob.GetState(out state);
            Status = (DownloadStatus)(int)state;

            _BG_JOB_PROGRESS progress;

            bitsJob.GetProgress(out progress);
            BytesTotal       = progress.BytesTotal;
            BytesTransferred = progress.BytesTransferred;

            bitsJob.SetNotifyInterface(this);

            IEnumBackgroundCopyFiles enumFiles = null;

            try {
                bitsJob.EnumFiles(out enumFiles);
                uint fetched;
                IBackgroundCopyFile file;
                enumFiles.Next(1, out file, out fetched);
                if (fetched == 1)
                {
                    string remoteUrl;
                    file.GetRemoteName(out remoteUrl);
                    RemoteUrl = remoteUrl;

                    string localName;
                    file.GetLocalName(out localName);
                    LocalFile = localName;
                }
            } finally {
                if (enumFiles != null)
                {
                    Marshal.ReleaseComObject(enumFiles);
                }
            }
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        /// <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;
                }
            }
        }
Пример #4
0
        private void RefreshJobProperties( )
        {
            _job.GetDisplayName(out _displayName);
            _job.GetDescription(out _description);
            _BG_JOB_PROGRESS jobProgress;

            _job.GetProgress(out jobProgress);
            _bytesTotal       = jobProgress.BytesTotal;
            _bytesTransferred = jobProgress.BytesTransferred;
            BG_JOB_STATE jobState;

            _job.GetState(out jobState);
            this.JobStateDescription = Enum.GetName(jobState.GetType(), jobState);
        }
Пример #5
0
        /// <summary>
        /// returns a job status enum for a particular job identified by its GUID
        /// </summary>
        /// <param name="jobId">a guid for the job requested</param>
        /// <returns>a JobStatus describing the state of the job</returns>
        JobStatus IDownloader.GetJobStatus(Guid jobId)
        {
            IBackgroundCopyManager backGroundCopyManager = null;
            IBackgroundCopyJob     backGroundCopyJob     = null;
            BG_JOB_STATE           state;
            string errMessage = "";
            string jobName    = "";
            string jobDesc    = "";
            string error      = "";

            try
            {
                backGroundCopyManager = (IBackgroundCopyManager) new BackgroundCopyManager();
                backGroundCopyManager.GetJob(ref jobId, out backGroundCopyJob);

                //  get job name
                backGroundCopyJob.GetDisplayName(out jobName);
                //  get job desc
                backGroundCopyJob.GetDescription(out jobDesc);
                //  get job state enum value
                backGroundCopyJob.GetState(out state);

                switch (state)
                {
                case BG_JOB_STATE.BG_JOB_STATE_ERROR:
                {
                    //  use utility method to handle error:
                    HandleDownloadErrorCancelJob(backGroundCopyJob, ref errMessage);

                    //  return status as error
                    return(JobStatus.Error);
                }

                case BG_JOB_STATE.BG_JOB_STATE_TRANSIENT_ERROR:
                {
                    //    NOTE:  if transient, just treat as full error.  During testing about 90% of transients
                    //				resulted in full failure.  Cleanup.
                    //  use utility method to handle error:
                    HandleDownloadErrorCancelJob(backGroundCopyJob, ref errMessage);

                    //  return status as error
                    return(JobStatus.Error);
                }

                case BG_JOB_STATE.BG_JOB_STATE_TRANSFERRED:
                {
                    //  tell BITS to transfer to us and stop thinking about the job
                    backGroundCopyJob.Complete();
                    // remove job from collection to be Dispose()ed
                    RemoveCopyJobEntry(jobId);
                    return(JobStatus.Ready);
                }

                case BG_JOB_STATE.BG_JOB_STATE_CANCELLED:
                {
                    //  use utility method to handle error:
                    HandleDownloadErrorCancelJob(backGroundCopyJob, ref errMessage);

                    //  return status as cancelled
                    return(JobStatus.Cancelled);
                }

                default:
                    return(JobStatus.Downloading);
                }
            }
            catch (ThreadInterruptedException tie)
            {
                //  if interrupted, clean up job
                HandleDownloadErrorCancelJob(backGroundCopyJob, ref errMessage);
                ApplicationUpdateManager.TraceWrite(tie, "[BITSDownloader.Download]", "RES_TIEInBITS", "N/A");
                throw tie;
            }
            catch (Exception e)
            {
                //  use utility method to handle error:
                HandleDownloadErrorCancelJob(backGroundCopyJob, ref errMessage);
                //  bad to catch all exceptions, but OK because we adorn it with necessary additional info then pass it up as innerException
                error = ApplicationUpdateManager.TraceWrite(e, "[BITSDownloader.GetJobStatus]", "RES_EXCEPTION_BITSOtherError", jobId, jobName, jobDesc);
                //  publish
                Exception newE = new Exception(error, e);
                ExceptionManager.Publish(newE);
                //  rethrow;
                throw newE;
            }
            finally
            {
                if (backGroundCopyManager != null)
                {
                    Marshal.ReleaseComObject(backGroundCopyManager);
                }
                if (backGroundCopyJob != null)
                {
                    Marshal.ReleaseComObject(backGroundCopyJob);
                }
            }
        }
        /// <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;
                }
            }
        }