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