/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! An interface for managing and monitoring BITS jobs. //! //! BITS is a Windows service for performing downloads in the background, independent from an //! application, usually via HTTP/HTTPS. //! //! [`BitsClient`](enum.BitsClient.html) is the main interface, used to issue commands. //! //! [`BitsMonitorClient`](enum.BitsMonitorClient.html) delivers periodic status reports about a //! job. //! //! Microsoft's documentation for BITS can be found at //! <https://docs.microsoft.com/en-us/windows/desktop/Bits/background-intelligent-transfer-service-portal>
// These errors would come from a Local Service client but are mostly unused currently. // PipeError properly lives in the crate that deals with named pipes, but it isn't in use now. #[derive(Clone, Debug, Eq, Error, PartialEq)] pubenum PipeError { #[error("Pipe is not connected")]
NotConnected, #[error("Operation timed out")]
Timeout, #[error("Should have written {0} bytes, wrote {1}")]
WriteCount(usize, u32), #[error("Windows API error")]
Api(HResult),
}
/// A client for interacting with BITS. /// /// Methods on `BitsClient` return a `Result<Result<_, XyzFailure>, Error>`. The outer `Result` /// is `Err` if there was a communication error in sending the associated command or receiving /// its response. Currently this is always `Ok` as all clients are in-process. The inner /// `Result` is `Err` if there was an error executing the command. /// /// A single `BitsClient` can be used with multiple BITS jobs simultaneously; generally a job /// is not bound tightly to a client. /// /// A `BitsClient` tracks all [`BitsMonitorClient`s](enum.BitsMonitorClient.html) that it started /// with `start_job()` or `monitor_job()`, so that the monitor can be stopped or modified. pubenum BitsClient { // The `InProcess` variant does all BITS calls directly. #[doc(hidden)]
InProcess(in_process::InProcessClient), // Space is reserved here for the LocalService variant, which will work through an external // process running as Local Service.
}
use BitsClient::InProcess;
impl BitsClient { /// Create an in-process `BitsClient`. /// /// `job_name` will be used when creating jobs, and this `BitsClient` can only be used to /// manipulate jobs with that name. /// /// `save_path_prefix` will be prepended to the local `save_path` given to `start_job()`, it /// must name an existing directory. pubfn new(
job_name: ffi::OsString,
save_path_prefix: ffi::OsString,
) -> Result<BitsClient, Error> {
Ok(InProcess(in_process::InProcessClient::new(
job_name,
save_path_prefix,
)?))
}
/// Start a job to download a single file at `url` to local path `save_path` (relative to the /// `save_path_prefix` given when constructing the `BitsClient`). /// /// `save_path_prefix` combined with `save_path` must name a file (existing or not) in an /// existing directory, which must be under the directory named by `save_path_prefix`. /// /// `proxy_usage` determines what proxy will be used. /// /// When a successful result `Ok(result)` is returned, `result.0.guid` is the id for the /// new job, and `result.1` is a monitor client that can be polled for periodic updates, /// returning a result approximately once per `monitor_interval_millis` milliseconds. pubfn start_job(
&mutself,
url: ffi::OsString,
save_path: ffi::OsString,
proxy_usage: BitsProxyUsage,
no_progress_timeout_secs: u32,
monitor_interval_millis: u32,
custom_headers: ffi::OsString,
) -> Result<Result<(StartJobSuccess, BitsMonitorClient), StartJobFailure>, Error> { matchself {
InProcess(client) => Ok(client
.start_job(
url,
save_path,
proxy_usage,
no_progress_timeout_secs,
monitor_interval_millis,
custom_headers,
)
.map(|(success, monitor)| (success, BitsMonitorClient::InProcess(monitor)))),
}
}
/// Start monitoring the job with id `guid` approximately once per `monitor_interval_millis` /// milliseconds. /// /// The returned `Ok(monitor)` is a monitor client to be polled for periodic updates. /// /// There can only be one ongoing `BitsMonitorClient` for each job associated with a given /// `BitsClient`. If a monitor client already exists for the specified job, it will be stopped. pubfn monitor_job(
&mutself,
guid: Guid,
interval_millis: u32,
) -> Result<Result<BitsMonitorClient, MonitorJobFailure>, Error> { matchself {
InProcess(client) => Ok(client
.monitor_job(guid, interval_millis)
.map(BitsMonitorClient::InProcess)),
}
}
/// Set the priority of job `guid`. /// /// `foreground == true` will set the priority to `BG_JOB_PRIORITY_FOREGROUND`, /// `false` will use the default `BG_JOB_PRIORITY_NORMAL`. /// See the Microsoft documentation for `BG_JOB_PRIORITY` for details. /// /// A job created by `start_job()` will be foreground priority, by default. pubfn set_job_priority(
&mutself,
guid: Guid,
foreground: bool,
) -> Result<Result<(), SetJobPriorityFailure>, Error> { matchself {
InProcess(client) => Ok(client.set_job_priority(guid, foreground)),
}
}
/// Set the "no progress timeout" of job `guid`. pubfn set_no_progress_timeout(
&mutself,
guid: Guid,
timeout_secs: u32,
) -> Result<Result<(), SetNoProgressTimeoutFailure>, Error> { matchself {
InProcess(client) => Ok(client.set_no_progress_timeout(guid, timeout_secs)),
}
}
/// Change the update interval for an ongoing monitor of job `guid`. pubfn set_update_interval(
&mutself,
guid: Guid,
interval_millis: u32,
) -> Result<Result<(), SetUpdateIntervalFailure>, Error> { matchself {
InProcess(client) => Ok(client.set_update_interval(guid, interval_millis)),
}
}
/// Complete the job `guid`. /// /// This also stops any ongoing monitor for the job. pubfn complete_job(&mutself, guid: Guid) -> Result<Result<(), CompleteJobFailure>, Error> { matchself {
InProcess(client) => Ok(client.complete_job(guid)),
}
}
/// Cancel the job `guid`. /// /// This also stops any ongoing monitor for the job. pubfn cancel_job(&mutself, guid: Guid) -> Result<Result<(), CancelJobFailure>, Error> { matchself {
InProcess(client) => Ok(client.cancel_job(guid)),
}
}
}
/// The client side of a monitor for a BITS job. /// /// It is intended to be used by calling `get_status` in a loop to receive notifications about /// the status of a job. Because `get_status` blocks, it is recommended to run this loop on its /// own thread. pubenum BitsMonitorClient {
InProcess(in_process::InProcessMonitor),
}
impl BitsMonitorClient { /// `get_status` will return a result approximately every `monitor_interval_millis` /// milliseconds, but in case a result isn't available within `timeout_millis` milliseconds /// this will return `Err(Error::Timeout)`. Any `Err` returned, including timeout, indicates /// that the monitor has been stopped; the `BitsMonitorClient` should then be discarded. /// /// As with methods on `BitsClient`, `BitsMonitorClient::get_status()` has an inner `Result` /// type which indicates an error returned from the server. Any `Err` here also indicates that /// the monitor has stopped after yielding the result. /// /// The first time `get_status` is called it will return a status without any delay. /// /// If there is an error or the transfer completes, a result may be available sooner than /// the monitor interval. pubfn get_status(
&mutself,
timeout_millis: u32,
) -> Result<Result<JobStatus, HResultMessage>, Error> { matchself {
BitsMonitorClient::InProcess(client) => client.get_status(timeout_millis),
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-06-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.