共用方式為


IBackgroundCopyCallback2 介面 (bits3_0.h)

實作這個介面,以接收檔案已完成下載的 通知 。 用戶端會使用此介面,而不是輪詢檔案的下載狀態。

若要接收通知,請呼叫 IBackgroundCopyJob::SetNotifyInterface 方法,以指定 IBackgroundCopyCallback 實作的介面指標。 若要指定您想要接收的通知,請呼叫 IBackgroundCopyJob::SetNotifyFlags 方法。

您必須實作這個介面和 IBackgroundCopyCallback 介面的所有方法。 例如,如果您未註冊傳輸的檔案回呼, 您的 FileTransferred 方法仍必須 傳回S_OK。 如果您不想接收傳送的檔案回呼,您可以改為實作 IBackgroundCopyCallback

繼承

IBackgroundCopyCallback2 介面繼承自 IBackgroundCopyCallbackIBackgroundCopyCallback2 也有下列類型的成員:

方法

IBackgroundCopyCallback2 介面具有這些方法。

 
IBackgroundCopyCallback2::FileTransferred

BITS 會在 BITS 成功完成傳輸檔案時,呼叫 FileTransferred 方法的實作。

備註

如需實作此介面的詳細資訊,請參閱 IBackgroundCopyCallback 介面。

範例

下列範例顯示 IBackgroundCopyCallback2 實作。 此範例也會示範如何在單個線程 Apartment 模型的 JobModification 回呼中處理重新進入呼叫。

#define TWO_GB 2147483648    // 2GB


class CNotifyInterface : public IBackgroundCopyCallback2
{
  LONG m_lRefCount;
  LONG m_PendingJobModificationCount;

public:
  //Constructor, Destructor
  CNotifyInterface() {m_lRefCount = 1; m_PendingJobModificationCount = 0;};
  ~CNotifyInterface() {};

  //IUnknown
  HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj);
  ULONG __stdcall AddRef();
  ULONG __stdcall Release();

  //IBackgroundCopyCallback methods
  HRESULT __stdcall JobTransferred(IBackgroundCopyJob* pJob);
  HRESULT __stdcall JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError);
  HRESULT __stdcall JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved);
  HRESULT __stdcall FileTransferred(IBackgroundCopyJob* pJob, IBackgroundCopyFile* pFile);
};

HRESULT CNotifyInterface::QueryInterface(REFIID riid, LPVOID* ppvObj) 
{
  if (riid == __uuidof(IUnknown) || 
      riid == __uuidof(IBackgroundCopyCallback) ||
      riid == __uuidof(IBackgroundCopyCallback2)) 
  {
    *ppvObj = this;
  }
  else
  {
    *ppvObj = NULL;
    return E_NOINTERFACE;
  }

  AddRef();
  return NOERROR;
}

ULONG CNotifyInterface::AddRef() 
{
  return InterlockedIncrement(&m_lRefCount);
}

ULONG CNotifyInterface::Release() 
{
  ULONG  ulCount = InterlockedDecrement(&m_lRefCount);

  if(0 == ulCount) 
  {
    delete this;
  }

  return ulCount;
}

HRESULT CNotifyInterface::JobTransferred(IBackgroundCopyJob* pJob)
{
  HRESULT hr;

  //Add logic that will not block the callback thread. If you need to perform
  //extensive logic at this time, consider creating a separate thread to perform
  //the work.

  hr = pJob->Complete();
  if (FAILED(hr))
  {
    //Handle error. BITS probably was unable to rename one or more of the 
    //temporary files. See the Remarks section of the IBackgroundCopyJob::Complete 
    //method for more details.
  }

  //If you do not return S_OK, BITS continues to call this callback.
  return S_OK;
}

HRESULT CNotifyInterface::JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError)
{
  HRESULT hr;
  BG_FILE_PROGRESS Progress;
  BG_ERROR_CONTEXT Context;
  HRESULT ErrorCode = S_OK;
  WCHAR* pszJobName = NULL;
  WCHAR* pszErrorDescription = NULL;
  BOOL IsError = TRUE;

  //Use pJob and pError to retrieve information of interest. For example,
  //if the job is an upload reply, call the IBackgroundCopyError::GetError method 
  //to determine the context in which the job failed. If the context is 
  //BG_JOB_CONTEXT_REMOTE_APPLICATION, the server application that received the 
  //upload file failed.

  hr = pError->GetError(&Context, &ErrorCode);

  //If the proxy or server does not support the Content-Range header or if
  //antivirus software removes the range requests, BITS returns BG_E_INSUFFICIENT_RANGE_SUPPORT.
  //This implementation tries to switch the job to foreground priority, so
  //the content has a better chance of being successfully downloaded.
  if (BG_E_INSUFFICIENT_RANGE_SUPPORT == ErrorCode)
  {
    hr = pError->GetFile(&pFile);
    hr = pFile->GetProgress(&Progress);
    if (BG_SIZE_UNKNOWN == Progress.BytesTotal)
    {
      //The content is dynamic, do not change priority. Handle as an error.
    }
    else if (Progress.BytesTotal > TWO_GB)
    {
      //BITS does not use range requests if the content is less than 2 GB. 
      //However, if the content is greater than 2 GB, BITS
      //uses 2 GB ranges to download the file, so switching to foreground 
      //priority will not help.
    }
    else
    {
      hr = pJob->SetPriority(BG_JOB_PRIORITY_FOREGROUND);
      hr = pJob->Resume();
      IsError = FALSE;
    }

    pFile->Release();
  }

  if (TRUE == IsError)
  {
    hr = pJob->GetDisplayName(&pszJobName);
    hr = pError->GetErrorDescription(LANGIDFROMLCID(GetThreadLocale()), &pszErrorDescription);

    if (pszJobName && pszErrorDescription)
    {
      //Do something with the job name and description. 
    }

    CoTaskMemFree(pszJobName);
    CoTaskMemFree(pszErrorDescription);
  }

  //If you do not return S_OK, BITS continues to call this callback.
  return S_OK;
}

HRESULT CNotifyInterface::JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved)
{
  HRESULT hr;
  WCHAR* pszJobName = NULL;
  BG_JOB_PROGRESS Progress;
  BG_JOB_STATE State;

  //If you are already processing a callback, ignore this notification.
  if (InterlockedCompareExchange(&m_PendingJobModificationCount, 1, 0) == 1)
  {
    return S_OK;
  }

  hr = pJob->GetDisplayName(&pszJobName);
  if (SUCCEEDED(hr))
  {
    hr = pJob->GetProgress(&Progress);
    if (SUCCEEDED(hr))
    {
      hr = pJob->GetState(&State);
      if (SUCCEEDED(hr))
      {
        //Do something with the progress and state information.
        //BITS generates a high volume of modification
        //callbacks. Use this callback with discretion. Consider creating a timer and 
        //polling for state and progress information.
      }
    }
    CoTaskMemFree(pszJobName);
  }

  m_PendingJobModificationCount = 0;

  return S_OK;
}

HRESULT CNotifyInterface::FileTransferred(IBackgroundCopyJob* pJob, IBackgroundCopyFile* pFile)
{
  HRESULT hr = S_OK;
  IBackgroundCopyFile3* pFile3 = NULL;
  BOOL IsValid = FALSE;

  hr = pFile->QueryInterface(__uuidof(IBackgroundCopyFile3), (void**)&pFile3);
  if (SUCCEEDED(hr))
  {
    // Add code to validate downloaded content and set IsValid.

    hr = pFile3->SetValidationState(IsValid);
    if (FAILED(hr))
    {
      // Handle error
    }

    pFile3->Release();
  }

	return S_OK;
}

規格需求

需求
最低支援的用戶端 Windows Vista
最低支援的伺服器 Windows Server 2008
目標平台 Windows
標頭 bits3_0.h (包含 Bits.h)

另請參閱

IBackgroundCopyCallback

IBackgroundCopyJob::SetNotifyFlags

IBackgroundCopyJob::SetNotifyInterface