Udostępnij za pośrednictwem


Kontrolowanie pobierania usługi BITS za pośrednictwem kosztownego połączenia

W tym temacie pokazano, jak zablokować zadanie BITS przed pobieraniem przez kosztowne połączenie, takie jak połączenie komórkowe w roamingu. BITS to asynchroniczny interfejs API, w którym aplikacja tworzy zadanie, dodaje adresy URL do tego zadania i wywołuje funkcję Resume obiektu zadania . Od tego czasu usługa BITS wybiera, kiedy zadanie jest pobierane, na podstawie takich czynników jak priorytet zadania i polityka transferu. Po zakończeniu pobierania zadania usługa BITS powiadamia aplikację o pobraniu adresu URL (jeśli aplikacja zarejestrowała się w celu powiadomienia o ukończeniu). W okresie istnienia zadania, jeśli sieć użytkownika końcowego ulegnie zmianie — na przykład jeśli użytkownik podróżuje i obecnie ponosi opłaty za roaming — usługa BITS zawiesi zadanie do momentu uzyskania optymalnych warunków sieciowych. Poniższe instrukcje krok po kroku pokazują, jak utworzyć zadanie i określić odpowiednie ustawienia zasad transferu.

Warunki wstępne

  • Microsoft Visual Studio

Instrukcje

Krok 1. Dołącz wymagane pliki nagłówkowe BITS

Wstaw następujące dyrektywy nagłówka na górze pliku źródłowego.

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

Krok 2: Zainicjuj COM

Przed utworzeniem wystąpienia interfejsu IBackgroundCopyManager (używanego do tworzenia zadania usługi BITS) należy zainicjować COM, ustawić model wątkowania dla COM i określić poziom impersonacji co najmniej 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))
 {
  ...

Krok 3. Utworzenie wystąpienia interfejsu IBackgroundCopyManager

Użyj interfejsu IBackgroundCopyManager, aby utworzyć zadania transferu, pobrać obiekt modułu wyliczającego zawierający zadania w kolejce i pobrać poszczególne zadania z kolejki.

IBackgroundCopyManager* pQueueMgr;

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

Krok 4. Tworzenie zadania usługi BITS

Tylko użytkownik tworzący zadanie lub użytkownik z uprawnieniami administratora może dodawać pliki do zadania i zmieniać właściwości zadania.

GUID guidJob;
IBackgroundCopyJob* pBackgroundCopyJob;

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

Krok 5. Określanie ustawienia zasad transferu dla zadania

W tym miejscu należy zdefiniować politykę transferu stanu kosztów. Można ustawić kilka flag BITS_COST_STATE przy użyciu bitowej kombinacji LUB w celu uzyskania pożądanych wyników.

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

Przykład

W poniższym przykładzie kodu pokazano, jak ustawić zasady transferu zadania usługi BITS, aby przetwarzanie zadania nie wystąpiło, gdy spełnione są pewne warunki — na przykład w przypadku roamingu lub przekroczenia miesięcznego limitu transferu danych.

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