다음을 통해 공유


비용이 많이 드는 연결을 통해 BITS 다운로드 제어

이 항목에서는 로밍 셀룰러 링크와 같은 비용이 많이 드는 연결을 통해 BITS 작업이 다운로드하지 못하도록 차단하는 방법을 보여 줍니다. BITS는 애플리케이션이 작업을 만들고, 해당 작업에 URL을 추가하고, 작업 개체의 Resume 함수를 호출하는 비동기 API입니다. 이 시점에서 BITS는 작업 우선 순위 및 전송 정책과 같은 요인에 따라 작업이 다운로드되는 시기를 선택합니다. 작업이 다운로드를 완료한 후 BITS는 애플리케이션에 URL이 다운로드되었음을 알 수 있습니다(애플리케이션이 완료 알림을 위해 등록한 경우). 작업 수명 동안 최종 사용자의 네트워크가 변경되는 경우(예: 사용자가 이동 중이고 현재 로밍 요금이 발생하는 경우) BITS는 네트워크 조건이 최적이 될 때까지 작업을 일시 중단합니다. 다음 단계별 지침에서는 작업을 만들고 적절한 전송 정책 설정을 지정하는 방법을 보여 줍니다.

사전 요구 사항

  • Microsoft Visual Studio

지침

1단계: 필요한 BITS 헤더 파일 포함

소스 파일의 맨 위에 다음 헤더 지시문을 삽입합니다.

#include <bits.h>
#include <bits5_0.h>

2단계: COM 초기화

IBackgroundCopyManager 인터페이스(BITS 작업을 만드는 데 사용됨)를 인스턴스화하기 전에 COM을 초기화하고 COM 스레딩 모델을 설정하고 최소 RPC_C_IMP_LEVEL_IMPERSONATE 가장 수준을 지정해야 합니다.

// Initialize COM and specify the COM threading model.
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
 // Specify an impersonation level of at least RPC_C_IMP_LEVEL_IMPERSONATE.
 hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
                           RPC_C_AUTHN_LEVEL_CONNECT,
                           RPC_C_IMP_LEVEL_IMPERSONATE,
                           NULL, EOAC_NONE, 0);
 if (SUCCEEDED(hr))
 {
  ...

3단계: IBackgroundCopyManager 인터페이스 인스턴스화

IBackgroundCopyManager 인터페이스를 사용하여 전송 작업을 만들고, 큐에 있는 작업이 포함된 열거자 개체를 검색하고, 큐에서 개별 작업을 검색합니다.

IBackgroundCopyManager* pQueueMgr;

hr = CoCreateInstance(__uuidof(BackgroundCopyManager),
                      NULL,
                      CLSCTX_LOCAL_SERVER,
                      __uuidof(IBackgroundCopyManager),
                      (void **)&pQueueMgr);

4단계: BITS 작업 만들기

작업을 만드는 사용자 또는 관리자 권한이 있는 사용자만 작업에 파일을 추가하고 작업의 속성을 변경할 수 있습니다.

GUID guidJob;
IBackgroundCopyJob* pBackgroundCopyJob;

hr = pQueueMgr->CreateJob(L"TransferPolicy",
                          BG_JOB_TYPE_DOWNLOAD,
                          &guidJob,
                          (IBackgroundCopyJob **)&pBackgroundCopyJob);

5단계: 작업에 대한 전송 정책 설정 지정

여기서 비용 상태 전송 정책을 지정합니다. 원하는 결과를 얻기 위해 비트 OR 조합을 사용하여 여러 BITS_COST_STATE 플래그를 설정할 수 있습니다.

BITS_JOB_PROPERTY_VALUE propval;
IBackgroundCopyJob5* pBackgroundCopyJob5;

propval.Dword = BITS_COST_STATE_USAGE_BASED
              | BITS_COST_STATE_OVERCAP_THROTTLED
              | BITS_COST_STATE_BELOW_CAP
              | BITS_COST_STATE_CAPPED_USAGE_UNKNOWN
              | BITS_COST_STATE_UNRESTRICTED;

hr = pBackgroundCopyJob->QueryInterface(__uuidof(IBackgroundCopyJob5),
                                        reinterpret_cast<void**>(&pBackgroundCopyJob5));
if(SUCCEEDED(hr))
{
 pBackgroundCopyJob5->SetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, propval);
}

예제

다음 코드 예제에서는 사용자가 로밍 중이거나 월별 데이터 전송 한도를 초과한 경우와 같이 특정 조건이 충족되는 동안 작업 처리가 발생하지 않도록 BITS 작업의 전송 정책을 설정하는 방법을 보여 줍니다.

//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <bits.h>
#include <stdio.h> // define wprintf


int main()
{
 HRESULT hr = S_OK;
 GUID guidJob;
 IBackgroundCopyJob5* pBackgroundCopyJob5;  
 IBackgroundCopyJob* pBackgroundCopyJob;
 IBackgroundCopyManager* pQueueMgr;
 BITS_JOB_PROPERTY_VALUE propval;

 // Specify the COM threading model.
 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 if (SUCCEEDED(hr))
 {
  // The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
  hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
                            RPC_C_AUTHN_LEVEL_CONNECT,
                            RPC_C_IMP_LEVEL_IMPERSONATE,
                            NULL, EOAC_NONE, 0);

  if (SUCCEEDED(hr))
  {
   hr = CoCreateInstance(__uuidof(BackgroundCopyManager), 
                         NULL,
                         CLSCTX_LOCAL_SERVER,
                         __uuidof(IBackgroundCopyManager),
                         (void **)&pQueueMgr);

   if (FAILED(hr))
   {
    // Failed to connect to BITS.
    wprintf(L"Failed to connect to BITS with error %x\n",hr);
    goto done;
   }

   // Create a BITS job.
   wprintf(L"Creating Job...\n");

   hr = pQueueMgr->CreateJob(L"TransferPolicy",
                             BG_JOB_TYPE_DOWNLOAD,
                             &guidJob,
                             (IBackgroundCopyJob **)&pBackgroundCopyJob);

   if (FAILED(hr))
   {
    wprintf(L"Failed to Create Job, error = %x\n",hr);
    goto cancel;
   }

   wprintf(L" Job is succesfully created ...\n");

   // Set the Transfer Policy for the job.
   propval.Dword = BITS_COST_STATE_USAGE_BASED 
                 | BITS_COST_STATE_OVERCAP_THROTTLED
                 | BITS_COST_STATE_BELOW_CAP
                 | BITS_COST_STATE_CAPPED_USAGE_UNKNOWN
                 | BITS_COST_STATE_UNRESTRICTED;

   hr = pBackgroundCopyJob->QueryInterface(
         __uuidof(IBackgroundCopyJob5),
         reinterpret_cast<void**>(&pBackgroundCopyJob5)
        );

   if (FAILED(hr))
   {
    wprintf(L"Failed to Create Job, error = %x\n",hr);
    goto cancel;
   }
   pBackgroundCopyJob5->SetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, propval);

   // Get the Transfer Policy for the new job.
   BITS_JOB_PROPERTY_VALUE actual_propval;

   wprintf(L"Getting TransferPolicy Property ...\n");

   hr = pBackgroundCopyJob5->GetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, 
                                         &actual_propval);
   if (FAILED(hr))
   {
    // SetSSLSecurityFlags failed.
    wprintf(L"GetProperty failed with error %x\n",hr);
    goto cancel;
   }

   DWORD job_transferpolicy = actual_propval.Dword;
   wprintf(L"get TransferPolicy Property returned %#x\n", job_transferpolicy);
  }
done:
  CoUninitialize();
 }
 return 1;

cancel:
 pBackgroundCopyJob->Cancel(); 
 pBackgroundCopyJob->Release();
 goto done;
}