从上传-回复作业中检索回复
除了将文件上传到服务器之外,BITS 上传-答复作业还将检查作为服务器答复的一部分发送的答复 URL,然后自动按照答复 URL 操作并从中下载响应。 有关 BITS-Reply-URL 标头值的更多详细信息,请参阅 Ack for Fragment 文档。
设置作业类型为 BG_JOB_TYPE_UPLOAD_REPLY,创建一个上传-答复类型的作业。 在作业进入 BG_JOB_STATE_TRANSFERRED 状态后,客户端可以使用答复数据。 若要检索答复,请调用以下方法之一:
IBackgroundCopyJob2::GetReplyData
提供答复数据的内存中副本。 使用此方法在调用 IBackgroundCopyJob::Complete 方法之前或之后读取答复数据。 如果答复数据超过 1 MB,则应用程序必须调用 IBackgroundCopyJob2::GetReplyFileName 方法,以检索答复文件的名称并直接读取其内容。
IBackgroundCopyJob2::GetReplyFileName
提供包含答复的文件的名称。 在打开和读取答复文件之前,必须调用 IBackgroundCopyJob::Complete 方法;在调用 Complete 方法之前,客户端无法使用答复文件。
仅在答复较小且可快速处理,以避免阻塞回调线程时,才在 IBackgroundCopyCallback::JobTransferred 方法中调用这些方法。 如果使用命令行通知而不是回调,请将作业标识符传递给可执行文件。 可执行文件使用作业标识符调用 Complete 方法,以使答复文件可用。
以下示例显示了如何使用每种方法来检索答复数据。
使用 GetReplyData
以下示例显示如何使用 IBackgroundCopyJob2::GetReplyData 方法检索答复数据。 该示例假定 IBackgroundCopyJob 接口指针有效,作业的类型为上传-答复,作业的状态为 BG_JOB_STATE_TRANSFERRED。
HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
BYTE* pReply = NULL;
UINT64 ReplySize;
//Need to query the IBackgroundCopyJob interface for an IBackgroundCopyJob2
//interface pointer. The IBackgroundCopyJob2 interface contains the GetReplyData method.
hr = pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
if (SUCCEEDED(hr))
{
hr = pJob2->GetReplyData(&pReply, &ReplySize);
if (S_OK == hr))
{
if (pReply)
{
//Do something with the data.
CoTaskMemFree(pReply);
}
else
{
//The server application did not return a reply.
}
}
else if (BG_E_TOO_LARGE == hr)
{
//The reply exceeds 1 MB. To retrieve the reply, get the reply file name,
//complete the job, open the reply file, and read the reply.
}
else
{
//Handle the error
}
pJob2->Release(); //When done, release the interface.
}
else
{
//Handle error. QueryInterface will return E_NOINTERFACE if the version of BITS
//running on the computer is less than BITS 1.5.
}
使用 GetReplyFileName
以下示例显示如何使用 IBackgroundCopyJob2::GetReplyFileName 方法检索答复数据。 该示例假定 IBackgroundCopyJob 接口指针有效,作业的类型为上传-答复,作业的状态为 BG_JOB_STATE_TRANSFERRED。
HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
WCHAR* pszFileName = NULL;
//Need to query the IBackgroundCopyJob interface for an IBackgroundCopyJob2
//interface pointer. The IBackgroundCopyJob2 interface contains the GetReplyFileName method.
hr = pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
if (SUCCEEDED(hr))
{
hr = pJob2->GetReplyFileName(&pszFileName);
if (SUCCEEDED(hr))
{
//Calling the Complete method removes the job from the queue,
//so make sure you maintain an interface pointer to this job
//or retrieve any job related information that you require
//when processing the reply.
hr = pJob->Complete();
//Open, read the file, and do something with the data.
CoTaskMemFree(pszFileName);
}
pJob2->Release(); //When done, release the interface.
}
else
{
//Handle error. QueryInterface will return E_NOINTERFACE if the version of BITS
//running on the computer is less than BITS 1.5.
}