/// <summary> /// Internal copy-job factory method. Used to coordinate all aspects of a job set-up, /// which includes creating a copy manager, creating a job within it, setting download /// parameters, and adding the job to our tracking collection for cleanup later /// </summary> /// <param name="copyManager">null reference to copy manager</param> /// <param name="copyJob">null reference to copy job</param> /// <param name="jobID">null reference to job id guid</param> /// <param name="jobName">string. Job name</param> /// <param name="jobDesc">string. Job description</param> /// <param name="task">DownloadTask. Used to get infos about credentials, proxy, etc.</param> private void CreateCopyJob( IBackgroundCopyManager copyManager, out IBackgroundCopyJob copyJob, ref Guid jobID, string jobName, string jobDesc, DownloadTask task) { // create the job, set its description, use "out" semantics to get jobid and the actual job object copyManager.CreateJob( jobName, BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out jobID, out copyJob); // set useful description copyJob.SetDescription(jobDesc); // *** // 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 copyJob.SetMinimumRetryDelay(BitsMinimumRetryDelay); // in constant set to 5 seconds; BITS will set job to Error status if exceeded copyJob.SetNoProgressTimeout(BitsNoProgressTimeout); // make this job the highest (but still background) priority-- copyJob.SetPriority(BG_JOB_PRIORITY.BG_JOB_PRIORITY_HIGH); // *** //---------------------------------------------------------------------- //-- Data Management and Research, Inc. - Paul Cox - 8/13/2004 //-- ADDED the following lines to verify credentials of file copy job //---------------------------------------------------------------------- // Set credentials on the job VerifyAndSetBackgroundCopyJobCredentials(copyJob, task); // Set proxy infos (incl Proxy Auth.) VerifyAndSetBackgroundCopyJobProxy(copyJob, task); //---------------------------------------------------------------------- //-- End ADDED //---------------------------------------------------------------------- // lock our internal collection of jobs, and add this job--we use this collection in Dispose() // to tell BITS to Cancel() jobs--and remove them from the queue // if we did not do this, BITS would continue for (by default) two weeks to download what we asked! lock (bitsDownloaderJobs.SyncRoot) { bitsDownloaderJobs.Add(jobID, jobName); } }
/// <summary> /// 检查/启动/结束传输作业进程,参数文件节点为空的取当前文件节点 /// </summary> /// <param name="nodeFile">要管理的传输文件节点</param> static private void HandleBits(Object o) { IBackgroundCopyManager bcm = null; IBackgroundCopyJob job = null; XmlNode nodeFile = null; nodeFile = BitsFileList.GetCurrentFile(); if (null == nodeFile) { return; } ((XmlElement)nodeFile).SetAttribute("state", "doing"); try { // Create BITS object bcm = (IBackgroundCopyManager) new BackgroundCopyManager(); Guid jobID = Guid.Empty; if (null != nodeFile.Attributes["jobguid"] && !string.IsNullOrEmpty(nodeFile.Attributes["jobguid"].Value)) { // Do we already have a job in place? jobID = new Guid(nodeFile.Attributes["jobguid"].Value); BG_JOB_STATE state; try { bcm.GetJob(ref jobID, out job); // Get the BITS job object job.GetState(out state); // check its state switch (state) { case BG_JOB_STATE.BG_JOB_STATE_ERROR: // If it is an error, re-poll job.Complete(); nodeFile.Attributes.RemoveNamedItem("jobguid"); Marshal.ReleaseComObject(job); job = null; break; case BG_JOB_STATE.BG_JOB_STATE_CANCELLED: case BG_JOB_STATE.BG_JOB_STATE_TRANSFERRED: // If we got the job job.Complete(); // then complete it nodeFile.ParentNode.RemoveChild(nodeFile); Marshal.ReleaseComObject(job); Marshal.ReleaseComObject(bcm); return; default: Marshal.ReleaseComObject(bcm); return; } } catch (Exception e) { NameValueCollection errInfo = new NameValueCollection(); errInfo["文件类别"] = nodeFile.Attributes["doctype"].Value; errInfo["远程文件"] = nodeFile.Attributes["srcurl"].Value; errInfo["作业Guid"] = nodeFile.Attributes["jobguid"].Value; ExceptionManager.Publish(e, errInfo); if (null != (e as UnauthorizedAccessException)) { if (job != null) { Marshal.ReleaseComObject(job); } if (bcm != null) { Marshal.ReleaseComObject(bcm); } return; } COMException exCOM = e as COMException; if (null != exCOM && exCOM.ErrorCode == unchecked ((Int32)0x80200001)) { nodeFile.Attributes.RemoveNamedItem("jobguid"); } else { return; } } } // Create a bits job to download the next expected update if (null != nodeFile && (null == nodeFile.Attributes["jobguid"] || string.IsNullOrEmpty(nodeFile.Attributes["jobguid"].Value))) { bcm.CreateJob("下载远程文件", BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out jobID, out job); string doctype = nodeFile.Attributes["doctype"].Value; string srcurl = nodeFile.Attributes["srcurl"].Value; string dest = nodeFile.Attributes["localname"].Value; job.SetDescription("下载文件位置: " + doctype); job.AddFile(srcurl, dest); job.Resume(); // start the job in action ((XmlElement)nodeFile).SetAttribute("jobguid", jobID.ToString()); } if (bcm != null) { Marshal.ReleaseComObject(bcm); } return; } catch { } }
/// <summary> /// Internal copy-job factory method. Used to coordinate all aspects of a job set-up, /// which includes creating a copy manager, creating a job within it, setting download /// parameters, and adding the job to our tracking collection for cleanup later /// </summary> /// <param name="copyManager">null reference to copy manager</param> /// <param name="copyJob">null reference to copy job</param> /// <param name="jobID">null reference to job id guid</param> /// <param name="jobNameKey">the key used to look up the job name in the resource file</param> /// <param name="jobDescriptionKey">the key used to look up the job description in the resource file</param> private void CreateCopyJob( out IBackgroundCopyManager copyManager, out IBackgroundCopyJob copyJob, ref Guid jobID, string jobNameKey, string jobDescriptionKey) { string jobName = Resource.ResourceManager[jobNameKey]; string jobDesc = Resource.ResourceManager[jobDescriptionKey]; // wrap in try-finally so we can clean COM objects if unexpected error try { // create the manager copyManager = (IBackgroundCopyManager) new BackgroundCopyManager(); // create the job, set its description, use "out" semantics to get jobid and the actual job object copyManager.CreateJob( jobName, BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out jobID, out copyJob); // set useful description copyJob.SetDescription(jobDesc); // *** // 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/ibackgroundcopyjob_setminimumretrydelay.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/ibackgroundcopyjob_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 copyJob.SetMinimumRetryDelay((uint)BITS_SET_MINIMUM_RETRY_DELAY); // in constant set to 5 seconds; BITS will set job to Error status if exceeded copyJob.SetNoProgressTimeout((uint)BITS_SET_NO_PROGRESS_TIMEOUT); // make this job the highest (but still background) priority-- copyJob.SetPriority(BG_JOB_PRIORITY.BG_JOB_PRIORITY_HIGH); // *** // lock our internal collection of jobs, and add this job--we use this collection in Dispose() // to tell BITS to Cancel() jobs--and remove them from the queue // if we did not do this, BITS would continue for (by default) two weeks to download what we asked! lock (_jobs.SyncRoot) { _jobs.Add(jobID, jobName); } } catch (Exception e) { // bad to catch all exceptions, but OK because we adorn it with necessary additional info then pass it up as innerException string error = ApplicationUpdateManager.TraceWrite(e, "[BITSDownloader.CreateCopyJob]", "RES_EXCEPTION_BITSOtherError", jobID, jobName, jobDesc); // publish Exception newE = new Exception(error, e); ExceptionManager.Publish(newE); // rethrow; throw newE; } }
/// <summary> /// Internal copy-job factory method. Used to coordinate all aspects of a job set-up, /// which includes creating a copy manager, creating a job within it, setting download /// parameters, and adding the job to our tracking collection for cleanup later /// </summary> /// <param name="copyManager">null reference to copy manager</param> /// <param name="copyJob">null reference to copy job</param> /// <param name="jobID">null reference to job id guid</param> /// <param name="jobNameKey">the key used to look up the job name in the resource file</param> /// <param name="jobDescriptionKey">the key used to look up the job description in the resource file</param> private void CreateCopyJob( out IBackgroundCopyManager copyManager, out IBackgroundCopyJob copyJob, ref Guid jobID, string jobNameKey, string jobDescriptionKey) { string jobName = Resource.ResourceManager[ jobNameKey ]; string jobDesc = Resource.ResourceManager[ jobDescriptionKey ]; // wrap in try-finally so we can clean COM objects if unexpected error try { // create the manager copyManager = (IBackgroundCopyManager) new BackgroundCopyManager(); // create the job, set its description, use "out" semantics to get jobid and the actual job object copyManager.CreateJob( jobName, BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out jobID, out copyJob ); // set useful description copyJob.SetDescription( jobDesc ); // *** // 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/ibackgroundcopyjob_setminimumretrydelay.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/ibackgroundcopyjob_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 copyJob.SetMinimumRetryDelay( (uint)BITS_SET_MINIMUM_RETRY_DELAY ); // in constant set to 5 seconds; BITS will set job to Error status if exceeded copyJob.SetNoProgressTimeout( (uint)BITS_SET_NO_PROGRESS_TIMEOUT ); // make this job the highest (but still background) priority-- copyJob.SetPriority( BG_JOB_PRIORITY.BG_JOB_PRIORITY_HIGH ); // *** // lock our internal collection of jobs, and add this job--we use this collection in Dispose() // to tell BITS to Cancel() jobs--and remove them from the queue // if we did not do this, BITS would continue for (by default) two weeks to download what we asked! lock( _jobs.SyncRoot ) { _jobs.Add( jobID, jobName ); } } catch( Exception e ) { // bad to catch all exceptions, but OK because we adorn it with necessary additional info then pass it up as innerException string error = ApplicationUpdateManager.TraceWrite( e, "[BITSDownloader.CreateCopyJob]", "RES_EXCEPTION_BITSOtherError", jobID, jobName, jobDesc ); // publish Exception newE = new Exception( error, e ); ExceptionManager.Publish( newE ); // rethrow; throw newE; } }