This article was written by Benjamin aka chaosben. He kindly agreed to publish it here. You can also publish articles here. Mail us @ mail(-at+)delphi-jedi.net

Getting started with BITS

BITS, the Background Intelligent Transfer Service, provides an easy way to
download/upload files from/to the network/internet. You may have heard of this
service in the context of the automatic Windows Update and you are right -
Microsoft uses it to get the files on the computer.

Ok, I know, you want to start coding. Thats why our first step is to add the
units ActiveX, ComObj and JwaBits to the uses clause of our project.
In the next step, we have ensure, that the COM library is initialized for the
current thread. It sounds hard, but it is easy (thanks to Sebastian):

initialization
  CoInitFlags := COINIT_APARTMENTTHREADED;

Just write this part at the end of your unit before the final “end.”

Fine, now we have a nice environment for messing around with BITS. Let’s
grab an interface to a BackgoundCopyMananger. After declaring a variable
(I call it “FManager”) of type IBackgroundCopyManager, it can be
initialized as follow:

Res := CoCreateInstance(CLSID_BackgroundCopyManager,
                        nil,
                        CLSCTX_LOCAL_SERVER,
                        IID_IBackgroundCopyManager,
                        FManager);
if not Succeeded(Res) then
  raise Exception.Create(‘Can not create BackgroundCopyManager.
                          Is the service running?’
);

Don’t forget to free the interface at the end of the program. Just write:

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(FMananger) then
    FMananger := nil;
end;

As our first test with BITS, we want to see, which jobs are currently running.
I dropped a listbox and a timer on a form and filled the OnTimer-Event with this code:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Job : IBackgroundCopyJob;
  Jobs : IEnumBackgroundCopyJobs;
  Res : HRESULT;
  DisplayName : PWideChar;
  Fetched : ULong;
begin
  ListBox1.Clear;

  //Try to get all jobs (hopefully we have the rights)
  Res := FManager.EnumJobs(BG_JOB_ENUM_ALL_USERS, Jobs);

  //maybe the right is missing … try to get just our jobs
if not Succeeded(Res) then
    Res := FManager.EnumJobs(0, Jobs);

  //nothing is ok … better go sleeping  :)
  if not Succeeded(Res) then
    raise Exception.Create(‘Can not enum BackgroundCopyJobs’);

  //walk through the enum of jobs …
  while Succeeded(Jobs.Next(1, Job, @Fetched)) and (Fetched = 1) do
  begin
    //… and try to get the name of each job
    if Succeeded(Job.GetDisplayName(DisplayName)) then
    begin
      ListBox1.Items.Add(DisplayName);

      //its important to free the memory, BITS allocated for us
      CoTaskMemFree(DisplayName);
    end;

    //release the job
    Job := nil;

  end;
end;

Ok, that’s it. Play around with the interface to get in touch with them.
Maybe another article will follow.

Benjamin aka chaosben
www.TheUnknownOnes.net

Part 2

You can get to the second part of BITS here.

Download

The new BITS header conversion units will be available through the JEDI API Release. They actually are not available. Thus we provide them as download here.

Notice:
The code examples above do not use these new units, however. Thus you can just include JwaBits.pas (or JwaWindows).

JwaBITS Download