I hope you enjoyed the first part of the introduction to BITS.
In this second part, we want to improve our job list (a little bit) and start own dowloads.
The first task is, to replace the old TListbox with a TListview. I switched the ViewStyle to vsReport and added 3 columns: Name, State, GUID. Saving the GUID of the job as a string is not fine but goes with my laziness.
We also have to change the code of the Timer. My whole OnTimer-Event looks like this:
Res := FManager.EnumJobs(BG_JOB_ENUM_ALL_USERS, Jobs);
if not Succeeded(Res) then
Res := FManager.EnumJobs(0, Jobs);
if not Succeeded(Res) then
raise Exception.Create(‘Can not enum BackgroundCopyJobs’);
while Succeeded(Jobs.Next(1, Job, @Fetched)) and (Fetched = 1) do
begin
Item := lv_Jobs.Items.Add;
Item.SubItems.Add(‘unknown’); //state of the job
Item.SubItems.Add(‘unknown’); //GUID of the job
if Succeeded(Job.GetDisplayName(DisplayName)) then
begin
Item.Caption := DisplayName;
CoTaskMemFree(DisplayName);
end;
if Succeeded(Job.GetState(State)) then
begin
case State of
BG_JOB_STATE_QUEUED: Item.SubItems[0] := ‘queued’;
BG_JOB_STATE_CONNECTING: Item.SubItems[0] := ‘connecting’;
BG_JOB_STATE_TRANSFERRING: Item.SubItems[0] := ‘transfering’;
BG_JOB_STATE_SUSPENDED: Item.SubItems[0] := ‘suspended’;
BG_JOB_STATE_ERROR: Item.SubItems[0] := ‘error’;
BG_JOB_STATE_TRANSIENT_ERROR: Item.SubItems[0] := ‘transient error’;
BG_JOB_STATE_TRANSFERRED: Item.SubItems[0] := ‘transferred’;
BG_JOB_STATE_ACKNOWLEDGED: Item.SubItems[0] := ‘acknowledged’;
BG_JOB_STATE_CANCELLED: Item.SubItems[0] := ‘cancelled’;
end;
end;
if Succeeded(Job.GetId(JobID)) then
Item.SubItems[1] := GUIDToString(JobID);
Job := nil;
end;
end;
Ok, this code will never win an art-award but is does what I want.
Now we have a fine list. But what is missing? Action … coders need interaction!
Thats why we add a TPopupMenu to the listview for these 4 actions: Resume, Suspend, Cancel, Complete. Each OnClick-Code may look like this:
So whats our state of affairs? There is a list of the current BITS-Jobs of our system. And we can control the states of the jobs. And – you are right – it’s still boring.
Starting a download job is very easy. Just put this code somewhere (for example in the OnClick-Event of a TButton):
Thats it.
Easy, isn’t it? Just run the app, click the button and watch the listview. If all went ok, the state of the job will switch from suspended via connecting, transferring to transferred.
Now its time to wonder: Where is my file?
The file is already there, although with another name. BITS creates temporary files, while downloading the content. These files are usally named like BIT*.tmp. In order to get the real file out of the temporary file, we have to call the Complete procedure of the corresponding job, when it has reached the state transferred. There are at least 2 ways to find out, if the job is ready to be completed: Poll the state of the job or implement the IBackgroundCopyCallback interface. The last way is the smart one and it minimizes the length of code. Only 4 steps are needed to implment this interface:
Now we can use our form as notfier for events of BITS-jobs. Just call the SetNotifyInterface function (with the form-instance as 1st param) of the Job after creating it. I put this code after the Job.Resume call. If you start the programm now and add the job again, it should disappear after getting transferred and the local file should appear in the location you have choosen.
But be aware: this notification is only working as long as the interface exists. If you start a download, shut down the programm and restart it without setting the notify interface again, you will never get informed about the complete transmission of the job.
That’s it. It remains to say: Play around with the interfaces and functions to get in touch with BITS.
Because: Playing is learning!
PS: You can download the project of this article here: example-bits-2
6 Responses
Jim McKeeth
01|May|2008 1Check out my page at http://www.davinciunltd.com/code/advanced-downloads-with-delphi/ for some more Delphi BITS programming related resources. I have a video of my presentation on the subject somewhere that I can put on for streaming if there is interest.
Getting started with BITS by JEDI Windows API
05|Jun|2008 2[...] You can get to the second part of BITS here. [...]
Jens
04|Jul|2010 3unfortunately, Job.AddFile always failes.
chaosben
05|Jul|2010 4“Failing” isn’t clear enough.
Please call the function RaiseLastOSError after AddFile to get the description of the cause.
Jens
05|Jul|2010 5Yes, you’re right.
I have tested on it and found out, that it works correctly on windows 7. My programming pc running xp shows the tasks added by windows update downloading correctly, where the “manually” added tasks are shown but always suspended as there are no files added.
RaiseLastOSError shows an EOSError “Ein Aufruf einer Betriebssystemfunktion ist fehlgeschlagen” (meaning that a call to a system function failed).
For me, this message is non-helping, it doesn’t tell me anything new. I suppose, there must be something wrong within windows, because windows update works correctly on the programming pc and this program works on 7. Nevertheless, the fact that wu works is irritating me.
Christian Wimmer
11|Jul|2010 6I don’t get it. Where does it fail and where does it work? Win7, XP ????
Leave a reply
You must be logged in to post a comment.
Search
Paypal donation (EUR)
Download Win 7 Search Provider
Categories
Archives
Tags
Recent Posts
Recent Comments
Blogroll
JEDI Sites
Pages
A design creation of Design Disease
Copyright © 2007 - JEDI Windows API - is proudly powered by WordPress
InSense 1.0 Theme by Design Disease brought to you by HostGator Web Hosting.