Bagikan melalui


Mengontrol unduhan BITS melalui koneksi yang mahal

Topik ini menunjukkan cara memblokir pekerjaan BITS agar tidak diunduh melalui koneksi mahal seperti tautan seluler roaming. BITS adalah API asinkron tempat aplikasi membuat pekerjaan, menambahkan URL ke pekerjaan tersebut, dan memanggil fungsi Resume objek pekerjaan. Dari titik itu, BITS memilih kapan pekerjaan diunduh berdasarkan faktor-faktor seperti prioritas pekerjaan dan kebijakan transfer. Setelah pekerjaan selesai diunduh, BITS memberi tahu aplikasi bahwa URL telah diunduh (jika aplikasi telah mendaftar untuk pemberitahuan penyelesaian). Selama masa pakai pekerjaan, jika jaringan pengguna akhir berubah—seperti jika pengguna bepergian dan saat ini dikenakan biaya roaming—maka BITS akan menangguhkan pekerjaan hingga kondisi jaringan optimal. Instruksi langkah demi langkah berikut menunjukkan cara membuat pekerjaan dan menentukan pengaturan kebijakan transfer yang sesuai.

Prasyarat

  • Microsoft Visual Studio

Petunjuk

Langkah 1: Sertakan file header BITS yang diperlukan

Sisipkan direktif header berikut di bagian atas file sumber.

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

Langkah 2: Inisialisasi COM

Sebelum membuat instans antarmuka IBackgroundCopyManager (digunakan untuk membuat pekerjaan BITS), Anda harus menginisialisasi COM, mengatur model utas COM, dan menentukan tingkat peniruan setidaknya 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))
 {
  ...

Langkah 3: Membuat instans antarmuka IBackgroundCopyManager

Gunakan antarmuka IBackgroundCopyManager untuk membuat pekerjaan transfer, mengambil objek enumerator yang berisi pekerjaan dalam antrean, dan mengambil pekerjaan individual dari antrean.

IBackgroundCopyManager* pQueueMgr;

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

Langkah 4: Membuat pekerjaan BITS

Hanya pengguna yang membuat pekerjaan atau pengguna dengan hak istimewa administrator yang dapat menambahkan file ke pekerjaan dan mengubah properti pekerjaan.

GUID guidJob;
IBackgroundCopyJob* pBackgroundCopyJob;

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

Langkah 5: Tentukan pengaturan kebijakan transfer untuk pekerjaan

Di sinilah Anda menentukan kebijakan transfer status biaya. Anda dapat mengatur beberapa bendera BITS_COST_STATE dengan menggunakan kombinasi OR bitwise untuk mencapai hasil yang diinginkan.

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);
}

Contoh

Contoh kode berikut menunjukkan cara mengatur kebijakan transfer pekerjaan BITS sehingga pemrosesan pekerjaan tidak terjadi saat kondisi tertentu terpenuhi—seperti ketika pengguna menjelajah atau telah melebihi batas transfer data bulanan mereka.

//*********************************************************
//
//    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;
}