Geeks With Blogs
Blog Moved to Blog Moved to
Update:  Put a comment in if you want the C# version of this code and I will get it to you

Well, I finally managed to get a spot for the Managed BITS Wrapper on  I have not uploaded any files just yet, as I am cleaning up one or two things as well as trying to add some test cases to it.  I will let people know when I actually have a release out there available.  The first available release will be in Managed C++ and then the second release will be in C++/CLI. 
I left off last time looking at some of the functions within the BackgroundCopyJob wrapper for IBackgroundCopyJob, IBackgroundCopyJob2, and IBackgroundCopyJob3.  I haven't bothered with IBackgroundCopyJob4 since it is available only on Vista for the time being.
Where I would like to go today is to cover how we're going to wrap the NotifyInterface methods and the IBackgroundCopyCallback interface in order to perform events on job transferred, job error and job modification.  This involves implementing a class with an unmanaged interface and wrapping it with a managed event manager. 
Below is the definition of the BackgroundCopyJobEventManager:  Note that it contains a lot of information to parse.
// This class encompasses NotifyInterface and the IBackgroundCopyCallBack
public __gc class BackgroundCopyJobEventManager : public System::IDisposable
     // Job error event handler
     __delegate void JobErrorEventHandler(Object* sender, BackgroundCopyErrorEventArgs* e);
     // Job modification event handler
     __delegate void JobModificationEventHandler(Object* sender, BackgroundCopyJobEventArgs* e);
     // Job transferred event handler
     __delegate void JobTransferredEventHandler(Object* sender, BackgroundCopyJobEventArgs* e);
     // Member variables
     JobErrorEventHandler* pJobErrorEvent;
     JobModificationEventHandler* pJobModificationEvent;
     JobTransferredEventHandler* pJobTransferredEvent;
     bool isDisposed;
     // Unmanaged event handler
     __nogc class UnmanagedEventManager : public IBackgroundCopyCallback
          gcroot<BackgroundCopyJobEventManager*> pCopyJobEventManager;
          LONG m_lRefCount;
          // Constructor that takes a BackgroundCopyJobEventManager
          UnmanagedEventManager(gcroot<BackgroundCopyJobEventManager*> pCopyJobEventManager);
          // Destructor
          ~UnmanagedEventManager() {}
          // IUnknown methods
          HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj);
          ULONG __stdcall AddRef();
          ULONG __stdcall Release();
          // Job error callback
          HRESULT __stdcall JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError);
          // Job modification callback
          HRESULT __stdcall JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved);
          // Job transferred callback
          HRESULT __stdcall JobTransferred(IBackgroundCopyJob* pJob);
     }; // class - UnmanagedEvents
     UnmanagedEventManager __nogc* pUnmanagedEvents;
     // Public constructor
     // Destructor
     // Dispose method
     __sealed void Dispose();
     // Add a job to monitor with default flags
     void AddBackgroundCopyJob(BackgroundCopyJob* pMonitoredJob);
     // Adds a job to monitor with the specified flags
     void AddBackgroundCopyJob(BackgroundCopyJob* pMonitoredJob, BackgroundCopyJobNotifyFlags notifyFlags);
     // Copy error event handler
     __event virtual void add_JobErrorEvent(JobErrorEventHandler* value);
     __event virtual void remove_JobErrorEvent(JobErrorEventHandler* value);
     // Job modification event handler
     __event virtual void add_JobModification(JobModificationEventHandler* value);
     __event virtual void remove_JobModification(JobModificationEventHandler* value);
     // Job transferred event handler
     __event virtual void add_JobTransferred(JobTransferredEventHandler* value);
     __event virtual void remove_JobTransferred(JobTransferredEventHandler* value);
public private:
     // The error event
     void ErrorEvent(BackgroundCopyJob* pErroredJob, BackgroundCopyError* pCopyError);
     // The modified event
     void ModificationEvent(BackgroundCopyJob* pModifiedJob);
     // The transferred event
     void TransferredEvent(BackgroundCopyJob* pTransferredJob);
     // Overloaded dispose method
     virtual void Dispose(bool disposing);
}; // class - BackgroundCopyJobEventManager
 So, let's cover this little by little.  We have an inner class called UnmanagedEvents which wraps the functionality in the IBackgroundCopyCallback.  As you can see, we also need to implement the IUnknown interface, as the IBackgroundCopyCallback does.  If you will also notice, I used the gcroot template which allows us to create managed types within unmanaged classes.
Since this is an unmanaged class, we must implement a destructor to clean up the code in the BackgroundCopyJobEventManager.  To save some time, I also implement the IDisposable interface as well so that cleanup can happen more quickly than waiting for the garbage collector to hit the destructor.
As you also notice, we have three event types, one for Transferred Events which occur when the job state is Transferred, one for Modified Events which occur when a job has been modified in any way, and one for Error Events which occur when there is an error associated with the BackgroundCopyJob.
That's it for today, but stay tuned for more.
Posted on Friday, June 2, 2006 11:44 AM Microsoft , Background Intelligent Transfer Service , .NET , Windows | Back to top

Comments on this post: Day 8 of the Background Intelligent Transfer Service (BITS) Managed Wrapper

No comments posted yet.
Your comment:
 (will show your gravatar)

Copyright © Matthew Podwysocki | Powered by: