C#调用BITS(Background Intellgent Transfer Service)
时间:2010-09-23 来源:飘遥(Zhenxing Zhou)
BITS(Background Intellgent Transfer Service)是微软推出的用来实现Client和Server之间进行文件传输的技术。微软只提供了基于COM的接口,而没有提供基于托管代码的封装。如果想用.NET上语言(如C#)需要我们手工对COM接口进行封装或使用第三方的封装,BITS有多个版本,找到合适的比较麻烦。MS没有提供TLB文件,也没把TLB文件嵌入到实现BITS的dll中,也就不能用tlbimp.exe工具生成COM的包装。如果有TLB文件,则可以用tlbimp.exe生成COM的包装程序集。
我在查看文件Windows SDK的时候,发现里面包含了各个版本的BITS的idl文件,midl.exe编译idl文件,发现生成TLB文件,tlbimp.exe发现能生成包装程序集,但有个问题,无论用哪个版本的idl文件,都只能生成BITS 1.0的COM接口的包装程序集;并且如果用bits4_0.idl生成的包装类,在创建BackgroundCopyManager4_0Class对象时,在两台Win7机器上实验,都出现异常,异常信息为:
Retrieving the COM class factory for component with CLSID {BB6DF56B-CACE-11DC-9992-0019B93A3A84} failed due to the following error: 80080005.
暂时没找到解决办法,我十分怀疑是MS的BUG。
4.0的不能用,就用3.0的,可只生成1.0的包装程序集不行啊。下面对bits3_0.idl文件进行手术进行手术:
我在查看文件Windows SDK的时候,发现里面包含了各个版本的BITS的idl文件,midl.exe编译idl文件,发现生成TLB文件,tlbimp.exe发现能生成包装程序集,但有个问题,无论用哪个版本的idl文件,都只能生成BITS 1.0的COM接口的包装程序集;并且如果用bits4_0.idl生成的包装类,在创建BackgroundCopyManager4_0Class对象时,在两台Win7机器上实验,都出现异常,异常信息为:
Retrieving the COM class factory for component with CLSID {BB6DF56B-CACE-11DC-9992-0019B93A3A84} failed due to the following error: 80080005.
暂时没找到解决办法,我十分怀疑是MS的BUG。
4.0的不能用,就用3.0的,可只生成1.0的包装程序集不行啊。下面对bits3_0.idl文件进行手术进行手术:
library BackgroundCopyManager3_0
{
[
uuid(659cdea7-489e-11d9-a9cd-000d56965251),
helpstring("Background copy manager 3.0")
]
coclass BackgroundCopyManager3_0
{
[default] interface IBackgroundCopyManager;
};
interface IBackgroundCopyJob4;
interface IBackgroundCopyJobHttpOptions;
interface IBackgroundCopyCallback2;
interface IBackgroundCopyFile3;
interface IBitsPeerCacheAdministration;
}
粗体部分是我们手工添加的,目的是生成TLB文件时,将粗体部分的interface包含进去,tlbimp.exe对这些接口进行包装。
命令行为:
{
[
uuid(659cdea7-489e-11d9-a9cd-000d56965251),
helpstring("Background copy manager 3.0")
]
coclass BackgroundCopyManager3_0
{
[default] interface IBackgroundCopyManager;
};
interface IBackgroundCopyJob4;
interface IBackgroundCopyJobHttpOptions;
interface IBackgroundCopyCallback2;
interface IBackgroundCopyFile3;
interface IBitsPeerCacheAdministration;
}
粗体部分是我们手工添加的,目的是生成TLB文件时,将粗体部分的interface包含进去,tlbimp.exe对这些接口进行包装。
命令行为:
midl bits3_0.idl
tlbimp bits3_0.tlb
最终生成BackgroundCopyManager3_0.dll文件,在.NET项目中添加引用即可。如果要从低版本的接口获得高版本的接口,需要低版本的接口调用QueryInterface,但对COM接口的包装会屏蔽引用计数及QueryInterface。翻一翻System.Runtime.InteropServices命名空间会发现Marshal类中有个QueryInterface的方法:
tlbimp bits3_0.tlb
最终生成BackgroundCopyManager3_0.dll文件,在.NET项目中添加引用即可。如果要从低版本的接口获得高版本的接口,需要低版本的接口调用QueryInterface,但对COM接口的包装会屏蔽引用计数及QueryInterface。翻一翻System.Runtime.InteropServices命名空间会发现Marshal类中有个QueryInterface的方法:
public static int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv);
这个问题解决。
写代码测试一下:
这个问题解决。
写代码测试一下:
using System;
using System.Runtime.InteropServices;
using BackgroundCopyManager3_0;
namespace www.Xianfen.Net
{
class Program
{
static void Main(string[] args)
{
BackgroundCopyManager3_0Class mgr = new BackgroundCopyManager3_0Class();
GUID guid;
IBackgroundCopyJob job;
//create job
mgr.CreateJob("job", BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out guid, out job);
//新版本interface的GUID.
Guid gJob4 = new Guid("659cdeae-489e-11d9-a9cd-000d56965251");
//获取老版本interface的指针
IntPtr pUnknwJob = Marshal.GetIUnknownForObject(job);
IntPtr pUnknwJob4;
//获取新版本interface的指针
int hresult = Marshal.QueryInterface(pUnknwJob, ref gJob4, out pUnknwJob4);
//获取新版本interface实例
IBackgroundCopyJob4 job4 = (IBackgroundCopyJob4)Marshal.GetObjectForIUnknown(pUnknwJob4);
job4.AddFile("http://www.xianfen.net/GRMSDKX_EN_DVD.iso", "C:\\WinSDK.iso");
job4.SetPriority(BG_JOB_PRIORITY.BG_JOB_PRIORITY_FOREGROUND);
//各种操作。。。
}
}
}
下载:修改后的bits3_0.idl、TLB文件及程序集下载
using System.Runtime.InteropServices;
using BackgroundCopyManager3_0;
namespace www.Xianfen.Net
{
class Program
{
static void Main(string[] args)
{
BackgroundCopyManager3_0Class mgr = new BackgroundCopyManager3_0Class();
GUID guid;
IBackgroundCopyJob job;
//create job
mgr.CreateJob("job", BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out guid, out job);
//新版本interface的GUID.
Guid gJob4 = new Guid("659cdeae-489e-11d9-a9cd-000d56965251");
//获取老版本interface的指针
IntPtr pUnknwJob = Marshal.GetIUnknownForObject(job);
IntPtr pUnknwJob4;
//获取新版本interface的指针
int hresult = Marshal.QueryInterface(pUnknwJob, ref gJob4, out pUnknwJob4);
//获取新版本interface实例
IBackgroundCopyJob4 job4 = (IBackgroundCopyJob4)Marshal.GetObjectForIUnknown(pUnknwJob4);
job4.AddFile("http://www.xianfen.net/GRMSDKX_EN_DVD.iso", "C:\\WinSDK.iso");
job4.SetPriority(BG_JOB_PRIORITY.BG_JOB_PRIORITY_FOREGROUND);
//各种操作。。。
}
}
}
下载:修改后的bits3_0.idl、TLB文件及程序集下载
相关阅读 更多 +