Click here to Skip to main content
15,123,118 members
Articles / Programming Languages / C#
Posted 4 Sep 2006


70 bookmarked

Forms Designer Friendly Background Intelligent Transfer Service (BITS) wrapper

Rate me:
Please Sign up or sign in to vote.
4.83/5 (18 votes)
4 Sep 2006CPOL6 min read
Create BITS copy jobs using the Forms Designer. All features of BITS are available, and easy to use managed wrapper with all COM interop details hidden.

Sample Image - Managed_BITS.png


There are a few articles about the Background Intelligent Transfer Service or BITS here. I wanted to add something more. Using BITS with COM interop isn't really difficult, but I thought this would be a fun project to do anyway.

For a complete reference on BITS, do read all about it on MSDN first.

When I started, I had some goals in mind.

  • Completely Forms Designer friendly that works as much like ListView and ListViewItem as possible.
  • Wrap all features of BITS through version 3.0.
  • Easy to use and relatively idiot proof. Someone's always making a better idiot, but I try.
  • Automatic handling of certain events. Fear not control freaks, all of the automatic handling can be shut off on a job by job basis.
  • All exceptions coming from my code derive from a common base class. You'll only need one catch handler. If I didn't throw the exception, then InnerException will contain the exception thrown by COM or the CLI.

Here's a simple example of creating a download job.

System.Net.BITS.Manager manager = new System.Net.BITS.Manager();
System.Net.BITS.Job job = new System.Net.BITS.Job("Simple Job");

job.Files.Add("", "c:\");

That's pretty easy. You could get away with doing this little. BITS will take care of the download, and IBackgroundCopyJob.Complete() will automatically be called when the job completes. If there's an error, IBackgroundCopyJob.Cancel() will automatically be called.

What this example lacks is a way to know when the job finishes. You can do this in one of two ways, using polling or events. Polling works just fine, use a timer to check the job state, or if you need something synchronous a simple loop will work.

while (job.State != JobState.Cancelled && 
       job.State != JobState.Acknowledged)

// we're done! Do Something

Of course, polling is not the best approach. The job will eventually finish one way or another, but the loop above could take a while. Let's use events instead.

    System.Net.BITS.Manager manager = new System.Net.BITS.Manager();
    System.Net.BITS.Job job = new System.Net.BITS.Job("Simple Job");

    manager.OnModfication += new 


private void manager_OnModfication(object sender, 
                     JobModificationEventArgs e)
    if (e.Job.State == JobState.Cancelled && 
        e.Job.State == JobState.Acknowledged)
        // we're done! Do Something

There's a lot more to BITS that what is in this example. Fortunately for me, it's documented by Microsoft already. I did add a few things, so I'll go over them. Not everything will be covered, just the important stuff.


Each version of BITS adds more features. Be sure to check what version of BITS was instantiated. An exception will be thrown if you try to use features from a higher version of BITS than what you have on your machine. You won't get the exception in the designer. You can set everything in the designer, you'll get the exception as soon as your code runs. Be careful not to set properties in the designer if you want to support older versions of BITS.

I didn't test everything! Sorry. I tested a lot of the functionality on both XP and Vista. I did not try an upload with reply job.

Not everything works as Microsoft has documented. When running on XP, if you set a command line notification, it will not run unless you set Job.EventsEnabled to false. Doing so means no events will fire for that job. You can still use polling. Command line notifications do work as documented on Vista. By the way, setting a command line notification in the OnTransferred event doesn't work. You have to set the command line sooner.

The documentation on MSDN is not up to date, and some of the stuff added in BITS version 3.0 is not documented.

If you have the System.Net.Bits assembly and the project that uses it in the same solution, Visual Studio can have problems in the designer. The sample project does this. I reference System.Net.BITS as a file reference not as a project reference, and whenever I change something in System.Net.BITS, I usually have to quit Visual Studio and rerun, otherwise the designer gets goofy.

The Manager Class

You will need to create an instance of Manager. You can create more than one, but one is all you need. It wraps IBackgroundCopyManager. It will try to instantiate the highest version of the BITS COM class. If BITS is not installed on your machine, you'll still be able to create a Manager, the constructor won't throw an exception. This will let you use the Forms Designer even when BITS is unavailable.

The Manager maintains the list of jobs. A job doesn't do anything unless it's in the Jobs collection. Just like ListViewItem, you can set its properties but its doesn't live until it's in a ListViewItemCollection. The Jobs collection is, by default, automatically populated with the jobs in IEnumBackgroundCopyJobs belonging to the current user. You can shut that off if you wish, or get all jobs belonging to all users. The Manager has an Update method. You can use Update to check IEnumBackgroundCopyJobs for new jobs, or remove jobs BITS no longer maintains. I.e., when one of your jobs completes, if you call JobCollection.Update(), your job will no longer be in the Jobs collection.

Jobs can be added or removed from the collection at any time. When removed from the collection, the IBackgroundCopyJob maintained by BITS still exists. If it was downloading before, it'll still be downloading. The job object is simply no longer connected to the IBackgroundCopyJob. This also means you can quit your app and your jobs will still be there when you start up again.

The Manager also has the job related events. Even though all events are connected to a job, it's much easier to connect to an event once than have to do it for each and every job. Not only that, BITS likes to send events as soon as possible, and often. By putting the events in the Manager class, you won't miss an event.

BITS likes to send lots of events and on different threads. BITS doesn't queue up events for the same job. You can have multiple events pre-empting each other. I think that's annoying. So I wrapped all the events in a Mutex.

The Job Class

For the most part, this is just a wrapper around IBackgroundCopyJob. Most things about a job are exposed as properties. Creating a job is not the same thing as creating the IBackgroundCopyJob. In order to support the designer, all of the designer settable properties are cached in the job until you call a method to create the actual IBackgroundCopyJob. I added a JobState for this case, called JobState.Inactive. When you construct the job, it will be in this state. If you call Job.Activate() or Job.Resume(), then the IBackgroundCopyJob is created. Any properties set at design time are set on the IBackgroundCopyJob. This is also when the files are added to the IBackgroundCopyJob as well.

Jobs can be cloned. All the job properties are set on the clone. Even the credentials. This will only work if you set all the credentials in this job instance. There's no way to get them from the IBackgroundCopyJob. So if your jobs collection was populated with an existing job, it won't have any credentials cached in it.

Jobs maintain a collection of files. While designing a job, you can add and removes files as you wish. Once the IBackgroundCopyJob is created, you can no longer remove files. For some reason, BITS doesn't support it.

Some properties, like ProxySettings, return a class. This is nice and handy, but there's a caveat. Don't go doing this.

job.ProxySettings.ProxyUsage = ProxyUsage.NoProxy;

It won't do anything. I could have made that work but decided against it. IBackgroundCopyJob.SetProxySettings() expects three arguments. If something is wrong with one of them, an exception is thrown. So if you want to change the proxy settings, you have to change them all at once.

JobProxySettings settings = job.ProxySettings;

settings.ProxyUsage = ProxyUsage.NoProxy;
job.ProxySettings.ProxyUsage = settings;

Doing the above will result in a call to IBackgroundCopyJob.SetProxySettings().



  • 09/04/2006: Posted to CodeProject.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior) Adobe, LLC
United States United States
No Biography provided

Comments and Discussions

QuestionWhy use Sytem in namespace Pin
Dave Krupa6-Jan-17 8:20
MemberDave Krupa6-Jan-17 8:20 
QuestionFacing an error in console application Pin
Member 989612719-Jun-13 22:32
MemberMember 989612719-Jun-13 22:32 
QuestionI keep getting error 405 when the job is upload . Pin
efka112-Jul-12 2:14
Memberefka112-Jul-12 2:14 
GeneralError with duplicates. Pin
mcockrum8-Jun-11 8:35
Membermcockrum8-Jun-11 8:35 
GeneralRe: Error with duplicates. Pin
zaxar016-Jan-12 2:11
Memberzaxar016-Jan-12 2:11 
GeneralProblem in Demo Pin
Shivam12345616-Jul-10 3:44
MemberShivam12345616-Jul-10 3:44 
QuestionIn my case, 1 file in my job takes forever to download? Pin
arane101030-Jun-10 18:43
Memberarane101030-Jun-10 18:43 
GeneralSolution Posted - RCW/COM Issues. (COM object that has been separated from its underlying RCW cannot be used) Pin
Mythias21-Jan-09 7:45
MemberMythias21-Jan-09 7:45 
GeneralRe: Solution Posted - RCW/COM Issues. (COM object that has been separated from its underlying RCW cannot be used) Pin
RodgerB30-Jan-09 13:19
MemberRodgerB30-Jan-09 13:19 
GeneralRe: Solution Posted - RCW/COM Issues. (COM object that has been separated from its underlying RCW cannot be used) Pin
spi13-Feb-09 23:11
professionalspi13-Feb-09 23:11 
QuestionDoes Anyone Have HTTPS / SSL Code Examples? Pin
Member 474177730-Sep-08 10:17
MemberMember 474177730-Sep-08 10:17 
GeneralPossible Bug Pin
sevenalive4-Jun-08 4:24
Membersevenalive4-Jun-08 4:24 
GeneralBe aware of security issue's and instable systems. Pin
Calibra200627-May-08 0:31
MemberCalibra200627-May-08 0:31 
GeneralThis is great, but i have a few questions. Pin
sevenalive20-May-08 3:46
Membersevenalive20-May-08 3:46 
GeneralRe: This is great, but i have a few questions. Pin
Calibra200626-May-08 23:45
MemberCalibra200626-May-08 23:45 
QuestionBITS Wrapper - SetCredentials Pin
shades4424-Apr-08 10:24
Membershades4424-Apr-08 10:24 
GeneralRe: BITS Wrapper - SetCredentials Pin
RodgerB24-Apr-08 11:36
MemberRodgerB24-Apr-08 11:36 
GeneralRe: BITS Wrapper - SetCredentials Pin
shades4428-Apr-08 13:03
Membershades4428-Apr-08 13:03 
GeneralRe: BITS Wrapper - SetCredentials Pin
TeaTime10-Jun-09 5:49
MemberTeaTime10-Jun-09 5:49 
GeneralRe: BITS Wrapper - SetCredentials Pin
TeaTime10-Jun-09 6:23
MemberTeaTime10-Jun-09 6:23 
QuestionCommand Line Pin
ghandlin31-Mar-08 11:23
Memberghandlin31-Mar-08 11:23 
GeneralRe: Command Line Pin
RodgerB31-Mar-08 14:02
MemberRodgerB31-Mar-08 14:02 
GeneralRe: Command Line Pin
ghandlin31-Mar-08 14:52
Memberghandlin31-Mar-08 14:52 
GeneralRe: Command Line Pin
RodgerB31-Mar-08 21:44
MemberRodgerB31-Mar-08 21:44 
GeneralRe: Command Line Pin
ghandlin1-Apr-08 4:31
Memberghandlin1-Apr-08 4:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.